Apa pertimbangan kinerja antara menggunakan PK luas vs kunci sintetis terpisah dan UQ?


10

Saya memiliki beberapa tabel di mana catatan dapat diidentifikasi secara unik dengan beberapa bidang bisnis yang luas. Di masa lalu, saya telah menggunakan bidang-bidang ini sebagai PK, dengan mempertimbangkan manfaat-manfaat ini:

  • Kesederhanaan; tidak ada bidang asing dan hanya satu indeks
  • Clustering memungkinkan penggabungan yang cepat dan filter berbasis jangkauan

Namun, saya pernah mendengar kasus yang dibuat untuk membuat IDENTITY INTPK sintetis , dan alih-alih menegakkan kunci bisnis dengan UNIQUEkendala terpisah . Keuntungannya adalah bahwa PK sempit menghasilkan indeks sekunder yang jauh lebih kecil.

Jika sebuah tabel tidak memiliki indeks selain PK, saya tidak melihat alasan untuk mendukung pendekatan kedua, meskipun dalam tabel besar mungkin lebih baik untuk mengasumsikan bahwa indeks mungkin diperlukan di masa depan, dan karena itu mendukung PK sintetis sempit . Apakah saya kehilangan pertimbangan?

Kebetulan, saya tidak berdebat menentang penggunaan kunci sintetis di gudang data, saya hanya tertarik kapan menggunakan PK luas dan kapan menggunakan PK sempit plus Inggris luas.


1
Anda mungkin menemukan ini atau ini membantu di antara pertanyaan lain di situs
Jack mengatakan coba topanswers.xyz

Jawaban:


11

Tidak ada kerugian signifikan menggunakan kunci alami sebagai indeks berkerumun

  • tidak ada indeks non-cluster
  • tidak ada kunci asing yang mereferensikan tabel ini (ini adalah baris induk)

Kelemahannya akan meningkat pemisahan halaman karena memasukkan data akan didistribusikan ke seluruh data, bukan di akhir.

Di mana Anda memiliki indeks FK atau NC, penggunaan indeks clustered yang sempit, numerik, dan meningkat memiliki kelebihan. Anda hanya mengulang beberapa byte data per entri NC atau FK, bukan kunci bisnis / natural.

Mengenai alasannya, baca juga 5 artikel dari Google

Catatan saya menghindari penggunaan "kunci utama".

Anda dapat memiliki indeks berkerumun pada kunci pengganti tetapi tetap menggunakan PK pada aturan bisnis tetapi sebagai non-cluster. Pastikan clustered itu unik karena SQL akan menambahkan "uniquifier" untuk membuatnya.

Akhirnya, mungkin masuk akal untuk memiliki kunci pengganti tetapi tidak secara membabi buta di setiap tabel : banyak-banyak tabel tidak membutuhkannya, atau di mana kunci gabungan dari tabel induk akan cukup


+1 untuk referensi artikel yang sangat baik Ny Tripp dalam pengindeksan.
Fabricio Araujo

2
+1 untuk titik bahwa kinerja tidak ada hubungannya dengan kunci utama dan semua yang berkaitan dengan indeks.
nvogel

4

Meskipun saya berisiko menyatakan yang jelas, indeks pada kunci pengganti (nomor id) berguna jika Anda perlu menemukan sesuatu berdasarkan nomor id mereka. Pengguna tidak akan berurusan dengan nomor id; mereka akan berurusan dengan teks yang bisa dibaca manusia. Jadi, Anda harus melewati banyak teks dan nomor id-nya, sehingga antarmuka pengguna dapat menampilkan teks dan beroperasi pada nomor id.

DMB akan menggunakan indeks semacam itu untuk mendukung kunci asing, jika Anda mendefinisikannya seperti itu.

Terkadang Anda dapat meningkatkan kinerja dengan menggunakan nomor id sebagai kunci asing, tetapi ini bukan peningkatan mutlak. Pada sistem OLTP kami, kunci asing menggunakan kunci alami mengungguli kunci asing menggunakan nomor id pada suite uji sekitar 130 (saya pikir) pertanyaan representatif. (Karena informasi penting sering dibawa dalam kunci, menggunakan kunci alami dihindari banyak bergabung.) Median speedup adalah faktor 85 (bergabung menggunakan nomor id butuh 85 kali lebih lama untuk mengembalikan baris).

Pengujian menunjukkan bahwa bergabung dengan nomor id tidak akan berkinerja lebih cepat daripada membaca pada kunci alami dalam database kami sampai tabel tertentu mencapai jutaan baris. Lebar baris banyak hubungannya dengan itu - baris yang lebih luas berarti lebih sedikit baris yang cocok pada satu halaman, jadi Anda harus membaca lebih banyak halaman untuk mendapatkan baris 'n'. Hampir semua tabel kami ada di 5NF; sebagian besar tabel cukup sempit.

Pada saat bergabung mulai melakukan pembacaan sederhana di sini , menempatkan tabel dan indeks kritis pada disk solid state dapat meratakan kinerja ke dalam ratusan juta baris.


3

Saya memiliki seluruh oltp database yang dirancang menggunakan kolom identitas untuk pengelompokan + pk. Ini bekerja sangat cepat pada insert / mencari tetapi saya telah melihat beberapa masalah:
1. opsi mengisi indeks tidak berguna karena memasukkan hanya terjadi pada akhir indeks
2. ruang penyimpanan lebih banyak. Saya memiliki tabel dengan puluhan juta catatan dan 1 int mengambil ruang dengan sendirinya. Setiap tabel dengan kolom identitas untuk pk harus memiliki indeks lain untuk pencarian bisnis, sehingga penyimpanan yang lebih dibutuhkan.
3. skalabilitas. Ini masalah terburuk. Karena setiap sisipan masuk ke akhir indeks, setiap sisipan hanya akan menekankan akhir indeks (alokasi, atau untuk menulis, dll). Dengan menggunakan kunci bisnis sebagai kunci pengelompokan Anda dapat mendistribusikan sisipan secara merata pada indeks. Itu berarti Anda baru saja menghilangkan hotspot besar. Anda dapat dengan mudah menggunakan lebih banyak file untuk indeks, setiap file pada drive terpisah, setiap drive bekerja secara terpisah.

Saya mulai mengubah tabel saya dari kolom identitas ke kunci alami (mungkin terpisah untuk pengelompokan & pk). Rasanya lebih baik sekarang.

Saya akan menyarankan yang berikut ini (setidaknya untuk oltp db):
1. gunakan sebagai kunci pengelompokan kolom yang tepat dalam urutan yang tepat untuk mengoptimalkan pertanyaan yang paling sering
2. gunakan pk kolom yang tepat yang masuk akal untuk tabel Anda

Jika kunci yang dikelompokkan tidak sederhana dan berisi karakter (char [], varchar, nvarchar), saya pikir jawabannya adalah 'itu tergantung', Anda harus menganalisis secara individual setiap kasus.

Saya menjaga prinsip berikut: mengoptimalkan permintaan paling umum sambil meminimalkan skenario terburuk.

Saya hampir lupa satu contoh. Saya punya beberapa tabel yang mereferensikan diri mereka sendiri. Jika tabel itu memiliki kolom identitas untuk kunci utama itu, maka memasukkan satu baris mungkin memerlukan pembaruan, dan memasukkan lebih dari satu baris pada satu waktu mungkin sulit jika bukan tidak mungkin (tergantung pada desain tabel).


4
Konsep "hotspot" Anda adalah mitos: dba.stackexchange.com/questions/1584/… Dan ketika Anda mengatakan "Rasanya lebih baik sekarang." apakah Anda patokan?
gbn

4
Yap, menulis dilakukan di memori tidak langsung ke disk. Jika Anda menulis 20 baris baru ke halaman, hanya ada 1 tulis fisik ke file data ketika pos pemeriksaan terjadi.
mrdenny

@ Mrdenny dengan sisipan cukup menulis semuanya ke akhir indeks akan mengirim semua permintaan menulis io ke file yang sama. Saya menduga bahwa menggunakan transaksi oltp normal, skenario ini akan sulit untuk direproduksi, tetapi menggunakan beberapa skenario khusus seperti catatan memasukkan massal / batch, menggunakan ssis untuk memindahkan beberapa data bisnis akan membawa Anda ke sana.
Catalin Adler

1
@ user973156 ya semua permintaan akan dilakukan ke file yang sama, tetapi penulisan tidak benar-benar pergi ke disk sampai pos pemeriksaan yang hanya terjadi setiap menit (secara default) atau ketika buffer tulis 50% penuh. Tidak masalah bagaimana Anda menulis data, aturan ini masih berlaku.
mrdenny

2
@ user973156 Menggunakan kunci cluster yang didistribusikan secara acak AKAN menyebabkan fragmentasi indeks. Fragmentasi indeks AKAN menyebabkan masalah kinerja. Dan tabel Anda akan menjadi cukup besar sehingga melakukan defragmentasi indeks akan memakan waktu "lama", dan memakan ruang log dan berpotensi ruang tempDB. Ketika saya memiliki orang-orang seperti Kimberly Tripp mengatakan kepada saya bahwa itu adalah ide yang baik, saya mendengarkan. ( sqlskills.com/BLOGS/KIMBERLY/post/… )
Matt M

2

Dari sudut pandang kinerja, pilihan kunci mana yang merupakan kunci "primer" tidak membuat perbedaan sama sekali. Tidak ada perbedaan antara menggunakan KUNCI UTAMA dan batasan UNIK untuk menegakkan kunci Anda.

Kinerja ditentukan oleh pemilihan dan jenis indeks dan opsi penyimpanan lain dan dengan cara kunci digunakan dalam kueri dan kode.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.