Saya memiliki kueri yang bergabung dengan beberapa tabel dan berkinerja sangat buruk - perkiraan baris adalah cara (1000 kali) mati dan Nested Loops bergabung dipilih, menghasilkan beberapa pemindaian tabel. Bentuk kueri cukup mudah, terlihat seperti ini:
SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id
WHERE t4.id = some_GUID
Bermain-main dengan kueri, saya perhatikan bahwa ketika saya mengisyaratkan untuk menggunakan gabungan Gabung untuk salah satu gabungan, itu berjalan beberapa kali lebih cepat. Ini bisa saya mengerti - Gabung bergabung adalah pilihan yang lebih baik untuk data yang bergabung, tetapi SQL Server hanya tidak memperkirakannya dengan benar memilih Nested Loops.
Apa yang saya tidak sepenuhnya mengerti adalah mengapa petunjuk ini mengubah semua perkiraan untuk semua operator paket? Dari membaca berbagai artikel dan buku, saya berasumsi bahwa estimasi kardinalitas dilakukan sebelum rencana dibuat, jadi menggunakan petunjuk tidak akan mengubah estimasi, tetapi lebih tepatnya memberitahu SQL Server untuk menggunakan implementasi join fisik tertentu.
Apa yang saya lihat, bagaimanapun, adalah bahwa Merge hint menyebabkan semua estimasi menjadi sangat sempurna. Mengapa ini terjadi dan apakah ada teknik umum untuk membuat pengoptimal kueri membuat perkiraan yang lebih baik tanpa petunjuk - mengingat statistik jelas memungkinkan untuk ini?
UPD: rencana eksekusi yang dianonimkan dapat ditemukan di sini: https://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl=0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hints_join.sqlplan?dl = 0
Saya memeriksa statistik yang digunakan oleh kedua pertanyaan menggunakan TF 3604, 9292 dan 9204, dan itu identik. Namun indeks yang dipindai / dicari berbeda di antara kueri.
Selain itu, saya mencoba menjalankan kueri dengan OPTION (FORCE ORDER)
- itu berjalan lebih cepat daripada menggunakan gabungan bergabung, memilih HASH MATCH untuk setiap bergabung.