Kami memiliki basis data besar ini (> 1TB) yang kami maksudkan untuk "menyusut". Basis data berputar di sekitar satu entitas utama, sebut saja "Kunjungi". Untuk diskusi, katakanlah ini adalah basis data untuk praktik medis.
Ada total 30 "jenis" kunjungan, seperti prosedur, tahunan, tindak lanjut, imunisasi dll, yang masing-masing merupakan tabel tambahan untuk "Kunjungi", misalnya "visit_immuno".
Basis data telah mengakumulasikan sekitar 12 tahun data sejak tahun 2000. Seseorang telah mengusulkan agar kami menyimpan sekitar 3 tahun data dalam versi "live" dan sisanya tinggal dalam database "old_data". Tanggal HANYA disimpan dalam tabel "Kunjungan" karena dinormalisasi. Tabel Kunjungan juga berisi ROWVERSION
kolom dan kolom BIGINT
identitas palsu (berkerumun). Untuk semua maksud dan tujuan, katakanlah kunci pengelompokan diisi oleh SEQUENCE (SQL Server 2012 Enterprise) - kami akan menamainya cid
.
Tidak visit.date
selalu dalam urutan yang sama dengan kunci pengelompokan, misalnya ketika seorang dokter melakukan kunjungan yang diperpanjang dan kembali dengan "koper" datanya, itu akan digabungkan ke dalam tabel utama. Ada juga beberapa pembaruan pada tabel "kunjungan" yang akan menyebabkan ROWVERSION
kolom tidak sinkron dengan kolom cid
dan date
- untuk membuatnya lebih sederhana, tidak ROWVERSION
juga tidak cid
akan membuat kunci partisi yang sesuai untuk alasan ini.
Aturan bisnis untuk menghapus data dari "langsung" adalah bahwa visit.date
harus lebih dari 36 bulan danvisit_payment
catatan anak harus ada. Juga, database "old_data" tidak mengandung tabel dasar kecuali visit%
.
Jadi kita berakhir dengan:
Live DB (penggunaan sehari-hari) - Semua tabel Data Lama DB - data lama untuk visit%
tabel
Proposal membutuhkan DB Gabungan yang merupakan shell yang berisi Sinonim untuk SEMUA tabel dasar dalam Live DB
(kecuali visit%
) plus Tampilan yang UNION ALL di seluruh visit%
tabel dalam dua database.
Dengan asumsi indeks yang sama dibuat di Old-Data
DB, apakah kueri berkinerja baik di UNION-ALL Views ? Jenis pola kueri apa yang mungkin meningkatkan rencana pelaksanaan untuk Tampilan UNION-ALL ?
Jawaban:
Untuk kenyamanan, anggaplah bahwa live database dipanggil
LiveDb
dan database yang berhasil disebutArchiveDb
LiveDb
menunjuk ke tabel dalamArchiveDb
database melalui sinonim (Tidak perlu melakukan db gabungan dengan sinonim)visit.date
dan nonaktifkan juga kolom inivisit_payments
jika belum ada (ini meningkatkan kinerja gabungan yang ditempatkan bersama)LiveDb
agar semua yang tergabung ke tabel yang lebih kecil disimpan secara lokalLiveDb
danArchiveDb
yang menjelaskan kisaran yangvisit.date
terkandung dalam tabel. Ini membantu optimiser menghilangkan tabel arsip dari pencarian dan pemindaian yang berisi kolomvisit.data
. Anda harus memperbarui batasan ini secara berkala.visit.data
. Ini merupakan tambahan untuk petunjuk yang telah Anda berikan dalam batasan pemeriksaan. Ini memaksimalkan kemungkinan filter ditekan ke bawahAchiveDb
mode pemulihan SEDERHANA jika belum. Anda tidak akan memerlukan cadangan log transaksiArchiveDb
LiveDb
danArchiveDb
Semua hal di atas tidak menjamin bahwa pengoptimal akan menghilangkan tabel arsip dari pencarian dan pemindaian, tetapi itu membuatnya lebih mungkin.
Ketika eliminasi tidak terjadi. Ini adalah efek yang mungkin Anda lihat (daftar ini mungkin tidak lengkap). Untuk mencari, Anda akan mendapatkan pencarian tambahan pada setiap permintaan (ini menaikkan IOPS). Untuk pemindaian, hasilnya bisa menjadi bencana bagi kinerja karena Anda dapat memindai tabel arsip dan tabel langsung. Berikut adalah cara-cara khas yang dapat Anda gunakan untuk meningkatkan optimizer:
visit%
tabel bersama dan tidak termasukvisit.data
dalam kriteria bergabung (inilah sebabnya Anda ingin menormalkan kembali). Karena itu, Anda mungkin ingin memodifikasi beberapa pertanyaan Andavisit.data
dan tabel lain (misalnya dimensi tanggal), Anda mungkin tidak mendapatkan penghapusan tabel yang benarvisit.data
, misalnya pencarian langsung pada kunci tampilan.Untuk skenario terakhir, Anda dapat melindungi diri Anda dari efek terburuk dengan menambahkan batasan pemeriksaan lain pada
cid
- jika ini memungkinkan. Anda memang menyebutkan bahwa urutancid
tidak "bersih" sehubungan dengan tanggal dan perkembangan baris dalam tabel. Namun, dapatkah Anda mempertahankan tabel yang berisi informasi: "Tidak adacid
nomor di atas ini sejak inivisit.data
" atau serupa? Ini kemudian dapat mendorong kendala tambahan.Hal lain yang perlu diperhatikan adalah bahwa kueri paralel dapat menghasilkan BANYAK utas lebih banyak setelah Anda meminta tampilan yang dipartisi (karena kedua "sub-tabel" akan terkena optimisasi paralel yang sama). Untuk alasan itu, Anda mungkin ingin membatasi MAXDOP di server atau kueri yang paralel.
Omong-omong, jika Anda tahu kueri dengan baik - Anda bahkan mungkin tidak perlu indeks yang sama di dua database (ini mengasumsikan Anda 100% yakin Anda akan mendapatkan penghapusan tabel yang tepat). Anda bahkan dapat mempertimbangkan menggunakan toko kolom untuk
ArchiveDb
.sumber
Cara yang kami lakukan adalah menulis data lama dalam batch ke database yang baru dibuat dan menghapus data lama dari live db. Dengan begitu kedua db dapat diakses. Anda juga dapat membuat cadangan database yang baru dibuat dan mengembalikannya di tempat lain untuk menghapus jejak besar dari server produksi. Semoga itu adalah solusi yang dapat diterima untuk kebutuhan Anda.
sumber