Saya mendesain daftar item yang akan (berpotensi) berisi puluhan juta rekaman. Beberapa item tidak akan tersedia untuk digunakan sampai mereka "disetujui" oleh administrator. Dengan "menggunakan" maksud saya bahwa barang-barang tersebut tidak akan dirujuk dalam tabel lain sampai mereka "disetujui". Hingga 50% item mungkin "tidak disetujui" pada waktu tertentu. Catatan mungkin menjadi "disetujui", tetapi tidak sebaliknya.
Saya mempertimbangkan dua opsi desain:
- bendera sedikit
- tabel terpisah dari item "tidak disetujui" - ketika item disetujui itu dipindahkan ke tabel "biasa" (pembaruan ID item tidak menjadi masalah)
Saya pikir opsi kedua jauh lebih baik. Bendera bit hanya membutuhkan satu byte per baris, jadi ini bukan masalah. Tetapi jika kita memiliki sejuta catatan yang disetujui dan satu juta catatan yang tidak disetujui dalam tabel yang sama - waktu pindai meningkat untuk operasi dengan catatan yang disetujui.
Pertanyaannya adalah: apakah saya harus mempertimbangkan opsi pertama (bit flag)? Apakah ada manfaatnya dalam situasi yang digambarkan?
WHERE status='A'
dan memiliki permintaanWHERE status = 'A' AND (... other columns and parameters here...)
, maka indeks tersebut mungkin masih digunakan.Jawaban:
Anda dapat memiliki keduanya dengan tampilan yang dipartisi .
Anda membuat tabel yang mendasari untuk setiap status, ditegakkan oleh kendala, dengan nilai-nilai yang saling eksklusif. Kemudian pandangan yang UNION bersama-sama tabel yang mendasarinya. Tampilan atau setiap tabel dasar dapat dirujuk secara eksplisit. Jika status baris adalah UPDATEd melalui tampilan, DBMS akan HAPUS dari satu tabel dasar dan masukkan ke yang sesuai dengan status baru. Setiap tabel dasar dapat diindeks secara independen sesuai dengan pola penggunaannya. Pengoptimal akan menyelesaikan referensi indeks ke satu tabel basis yang sesuai jika bisa.
Manfaatnya adalah
a) indeks dangkal. Akan tetapi, lakukan penghitungan indeks dengan menggunakan fan-out. Pada skala itu dan pisahkan antara nilai status Anda, mungkin indeksnya akan memiliki kedalaman yang sama pada tabel pisah seperti pada tabel gabungan.
b) tidak ada kode aplikasi yang harus diubah. Data terus muncul sebagai keseluruhan yang berkelanjutan.
c) nilai status baru di masa mendatang dapat dimasukkan dengan menambahkan tabel dasar baru, dengan kendala, dan menciptakan kembali tampilan.
Biaya adalah semua pergerakan data itu; dua halaman dan indeks terkait ditulis untuk setiap pembaruan status. Banyak IO yang harus dihadapi. Gerakan sebanyak itu akan menyebabkan fragmentasi juga.
sumber
Itu sebenarnya tidak banyak, mengingat apa yang SQL Server dapat efisien menangani. Tentu saja, saya ingat salah satu pekerjaan saya sebelumnya di mana salah satu meja terbesar (sistem instance-tunggal) memiliki 2 juta baris dan itu adalah yang paling saya pernah ditangani. Kemudian pekerjaan berikutnya memiliki 17 instance Produksi dengan beberapa tabel memiliki ratusan juta baris, dan semuanya dikumpulkan ke dalam Gudang Data dengan beberapa tabel fakta yang memiliki lebih dari 1 miliar baris. Jangan salah paham, saya tidak mengejek puluhan juta baris, saya hanya menekankan bahwa dengan model data yang baik dan pengindeksan yang tepat (dan pemeliharaan indeks), SQL Server dapat menangani banyak hal .
Hmm. Kedengarannya tidak benar. Tingkat entri "menyetujui" akan menjadi setengah tingkat mendapatkan entri baru? Untuk setiap 2 entri baru, hanya 1 yang akan "disetujui"? Dalam contoh Anda 2 juta baris, dan 1 juta masing-masing untuk "disetujui" dan "tidak disetujui", beberapa tahun kemudian dengan 10 juta entri lainnya, Anda mengharapkan masing-masing 6 juta untuk "disetujui" dan "tidak disetujui"? Atau apakah 1 juta "tidak disetujui" akan tetap agak konstan, sehingga dengan 10 juta entri baru, akan ada 11 juta "disetujui" dan masih 1 juta "tidak disetujui"?
Itu benar hari ini , tetapi banyak hal berubah dari waktu ke waktu sehingga selalu ada kemungkinan bahwa bisnis dapat memutuskan untuk mengizinkan "tidak disetujui", atau mungkin beberapa status lain, seperti "diarsipkan", dll.
Jadi, mari kita lihat pilihannya:
Tandai (atau bahkan
TINYINT
"status")TINYINT
kolomDua tabel terpisah (satu untuk "disetujui", satu untuk "tidak disetujui")
IDENTITY
kolom, dan meja Disetujui memiliki ID kolom yang tidak merupakanIDENTITY
(karena tidak dibutuhkan di sana). Karenanya nilai ID tetap konsisten saat rekaman bergerak di antara tabel.Secara pribadi, saya akan bersandar ke meja tunggal dengan
StatusID
kolom untuk memulai. Menggunakan dua tabel tampaknya seperti optimasi prematur yang terlalu rumit. Jenis optimasi itu dapat didiskusikan jika / ketika jumlah catatan dalam beberapa ratus juta dan pengindeksan tidak memberikan keuntungan kinerja apa pun.sumber