Apa algoritma internal tentang bagaimana operator Kecuali bekerja di bawah selimut di SQL Server? Apakah secara internal mengambil hash dari setiap baris dan membandingkan?
David Lozinksi menjalankan penelitian, SQL: Cara tercepat untuk menyisipkan catatan baru di mana orang belum ada. Dia menunjukkan Kecuali pernyataan adalah yang tercepat untuk baris jumlah besar; terikat erat dengan hasil kami di bawah ini.
Asumsi: Saya pikir Left join akan menjadi yang tercepat, karena hanya membandingkan 1 kolom, Kecuali akan memakan waktu paling lama, karena harus membandingkan Semua kolom.
Dengan hasil ini, sekarang pemikiran kita adalah Kecuali secara otomatis dan internal mengambil hash dari setiap baris? Saya melihat Kecuali rencana eksekusi dan tidak menggunakan beberapa hash.
Latar belakang: Tim kami membandingkan dua tabel tumpukan. Tabel A Baris tidak pada Tabel B, dimasukkan ke dalam Tabel B.
Heap tables (dari filesystem teks lama) tidak memiliki kunci utama / pengarah / pengidentifikasi. Beberapa tabel memiliki baris duplikat, jadi kami menemukan Hash setiap baris, dan menghapus duplikat, dan membuat pengidentifikasi kunci utama.
1) Pertama kami menjalankan pernyataan kecuali, tidak termasuk (kolom hash)
select * from TableA
Except
Select * from TableB,
2) Kemudian kami menjalankan perbandingan gabungan kiri antara dua tabel pada HashRowId
select *
FROM dbo.TableA A
left join dbo.TableB B
on A.RowHash = B.RowHash
where B.Hash is null
secara mengejutkan Sisipan Pernyataan Kecuali adalah yang tercepat.
Hasil sebenarnya memetakan dekat dengan hasil pengujian dari David Lozinksi
Jawaban:
Saya tidak akan mengatakan bahwa ada algoritma internal khusus untuk
EXCEPT
. SebabA EXCEPT B
, mesin mengambil tupel berbeda (jika perlu) dari A dan mengurangi baris yang cocok dengan B. Tidak ada operator rencana kueri khusus. Perbedaan dan pengurangan diterapkan melalui operator biasa yang akan Anda lihat dengan pengurutan atau dengan gabungan. Gabung bersarang loop, gabung gabung, dan gabung hash semua didukung. Untuk menunjukkan ini, saya akan membuang 15 juta baris ke dalam tumpukan:Pengoptimal menjadikannya keputusan berbasis biaya biasa tentang bagaimana menerapkan pengurutan dan bergabung. Dengan dua tumpukan saya mendapatkan hash bergabung seperti yang diharapkan. Anda bisa melihat tipe gabungan lainnya secara alami dengan menambahkan indeks atau dengan mengubah data di salah satu tabel. Di bawah ini saya memaksa gabungan dan loop bergabung dengan petunjuk hanya untuk tujuan ilustrasi:
Tidak. Ini diterapkan seperti yang lainnya. Salah satu perbedaannya adalah bahwa NULL diperlakukan sama. Ini adalah jenis khusus dari perbandingan yang dapat Anda lihat dalam rencana eksekusi:
<Compare CompareOp="IS">
. Namun, Anda bisa mendapatkan paket yang sama dengan T-SQL yang tidak menyertakanEXCEPT
kata kunci. Misalnya, berikut ini memiliki rencana kueri yang sama persis denganEXCEPT
kueri yang menggunakan hash bergabung:Diffing XML dari rencana eksekusi hanya mengungkapkan perbedaan dangkal di sekitar alias dan hal-hal seperti itu. Sisa probe untuk hash bergabung melakukan perbandingan baris. Mereka sama untuk kedua pertanyaan:
Jika Anda masih ragu, saya menjalankan PerfView dengan laju sampel tertinggi yang tersedia untuk mendapatkan tumpukan panggilan untuk kueri dengan
EXCEPT
dan kueri tanpa itu. Berikut adalah hasilnya secara berdampingan:Tidak ada perbedaan nyata. Tumpukan panggilan ada hashing referensi hadir karena cocok hash dalam rencana. Jika saya menambahkan indeks untuk menggabungkan gabungan alami, Anda tidak akan melihat referensi apa pun untuk hashing di tumpukan panggilan:
Setiap hashing yang terjadi adalah karena implementasi operator hash match. Tidak ada sesuatu yang istimewa tentang
EXCEPT
yang mengarah ke perbandingan hashing internal khusus.sumber