Paket kueri dengan filter bitmap terkadang sulit untuk dibaca. Dari artikel BOL untuk aliran partisi ulang (penekanan milik saya):
Operator Repartition Streams mengkonsumsi beberapa stream dan menghasilkan beberapa stream dari record. Isi dan format rekaman tidak diubah. Jika pengoptimal kueri menggunakan filter bitmap, jumlah baris dalam aliran output berkurang.
Selain itu, artikel tentang filter bitmap juga membantu:
Saat menganalisis rencana eksekusi yang mengandung penyaringan bitmap, penting untuk memahami bagaimana data mengalir melalui rencana dan di mana penyaringan diterapkan. Filter bitmap dan bitmap yang dioptimalkan dibuat pada sisi input build (tabel dimensi) dari hash join; Namun, pemfilteran yang sebenarnya biasanya dilakukan dalam operator Paralelisme, yang ada di sisi input probe (tabel fakta) dari hash join. Namun, ketika filter bitmap didasarkan pada kolom bilangan bulat, filter dapat diterapkan langsung ke tabel awal atau operasi pemindaian indeks daripada operator Parallelism. Teknik ini disebut optimasi in-row.
Saya percaya itulah yang Anda amati dengan permintaan Anda. Dimungkinkan untuk membuat demo yang relatif sederhana untuk menunjukkan operator aliran partisi ulang mengurangi perkiraan kardinalitas, bahkan ketika operator bitmap IN_ROW
menentang tabel fakta. Persiapan data:
create table outer_tbl (ID BIGINT NOT NULL);
INSERT INTO outer_tbl WITH (TABLOCK)
SELECT TOP (1000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values;
create table inner_tbl_1 (ID BIGINT NULL);
create table inner_tbl_2 (ID BIGINT NULL);
INSERT INTO inner_tbl_1 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
INSERT INTO inner_tbl_2 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
Berikut adalah kueri yang tidak boleh Anda jalankan:
SELECT *
FROM outer_tbl o
INNER JOIN inner_tbl_1 i ON o.ID = i.ID
INNER JOIN inner_tbl_2 i2 ON o.ID = i2.ID
OPTION (HASH JOIN, QUERYTRACEON 9481, QUERYTRACEON 8649);
Saya mengunggah paket tersebut . Lihatlah operator di dekat inner_tbl_2
:
Anda juga dapat menemukan tes kedua di Hash Joins on Nullable Columns oleh Paul White.
Ada beberapa inkonsistensi dalam bagaimana pengurangan baris diterapkan. Saya hanya bisa melihatnya dalam sebuah rencana dengan setidaknya tiga meja. Namun, pengurangan baris yang diharapkan tampaknya masuk akal dengan distribusi data yang tepat. Misalkan kolom yang tergabung dalam tabel fakta memiliki banyak nilai berulang yang tidak ada dalam tabel dimensi. Filter bitmap mungkin menghilangkan baris-baris itu sebelum mencapai gabungan. Untuk kueri Anda, estimasi dikurangi hingga 1. Bagaimana baris didistribusikan di antara fungsi hash memberikan petunjuk yang baik:
Berdasarkan itu saya menduga Anda memiliki banyak nilai berulang untuk Object1.Column21
kolom. Jika kolom berulang tidak berada dalam histogram statistik untuk Object4.Column19
kemudian SQL Server bisa mendapatkan perkiraan kardinalitas yang sangat salah.
Saya pikir Anda harus khawatir karena mungkin untuk meningkatkan kinerja kueri. Tentu saja, jika permintaan memenuhi waktu respons atau persyaratan SLA maka mungkin tidak perlu diselidiki lebih lanjut. Namun, jika Anda ingin menyelidiki lebih lanjut, ada beberapa hal yang dapat Anda lakukan (selain memperbarui statistik) untuk mengetahui apakah pengoptimal kueri akan memilih paket yang lebih baik jika memiliki informasi yang lebih baik. Anda bisa memasukkan hasil gabungan antara Database1.Schema1.Object10
dan Database1.Schema1.Object11
ke dalam tabel temp dan lihat apakah Anda terus mendapatkan gabungan simpul bersarang. Anda bisa mengubah gabungan LEFT OUTER JOIN
itu menjadi pengoptimal kueri tidak akan mengurangi jumlah baris pada langkah itu. Anda bisa menambahkan MAXDOP 1
petunjuk ke permintaan Anda untuk melihat apa yang terjadi. Anda bisa menggunakannyaTOP
bersama dengan tabel turunan untuk memaksa bergabung untuk pergi terakhir, atau Anda bahkan dapat mengomentari bergabung dari kueri. Semoga saran-saran ini cukup untuk membantu Anda memulai.
Mengenai item hubungkan dalam pertanyaan, sangat kecil kemungkinannya terkait dengan pertanyaan Anda. Masalah itu tidak ada hubungannya dengan taksiran baris yang buruk. Ini berkaitan dengan kondisi ras dalam paralelisme yang menyebabkan terlalu banyak baris diproses dalam rencana kueri di belakang layar. Di sini sepertinya kueri Anda tidak melakukan pekerjaan ekstra.