Saya melihat beberapa perilaku aneh dengan kueri T-SQL berikut di SQL Server 2012:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
Melaksanakan kueri ini sendiri memberi saya sekitar 1.300 hasil dalam waktu kurang dari dua detik (ada indeks teks lengkap aktif Name
)
Namun, ketika saya mengubah kueri untuk ini:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
OFFSET 0 rows
FETCH NEXT 10 ROWS ONLY
Butuh lebih dari 20 detik untuk memberi saya 10 hasil.
Permintaan berikut bahkan lebih buruk:
SELECT Id
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY Name) AS RowNum, Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"') ) AS RowConstrainedResult
WHERE RowNum >= 0 AND RowNum < 11
ORDER BY RowNum
Selesai lebih dari 1,5 menit!
Ada ide?
SELECT TOP 10 * .... ORDER BY Name
?Jawaban:
Karena Anda hanya ingin nama yang
TOP 10
dipesan, menurutnya akan lebih cepat untuk mengerjakan indeksname
dan melihat apakah setiap baris cocok denganCONTAINS(Name, '"John" AND "Smith"') )
predikat.Mungkin dibutuhkan lebih banyak baris untuk menemukan 10 pertandingan yang diperlukan kemudian diharapkan dan masalah kardinalitas ini diperparah dengan jumlah pencarian kunci.
Sebuah hack cepat untuk menghentikannya menggunakan rencana ini akan mengubah
ORDER BY
keORDER BY Name + ''
meskipun menggunakanCONTAINSTABLE
dalam hubungannya denganFORCE ORDER
juga harus bekerja.sumber
Ini terlihat seperti misestimasi selektivitas klasik. Tidak yakin apa yang dapat dilakukan tentang itu sebagai "driver" dari kueri adalah pencarian teks lengkap yang Anda tidak dapat menambah dengan statistik.
Cobalah menulis ulang
where contains
predikat keinner join containstable
( CONTAINSTABLE ) dan terapkan petunjuk bergabung pesanan untuk memaksa bentuk rencana.Itu bukan solusi yang sempurna karena memiliki masalah pemeliharaan, tetapi saya tidak bisa melihat cara lain.
sumber
Saya berhasil memecahkan masalah:
Seperti yang saya katakan dalam pertanyaan ada indikasi pada semua kolom + statistik untuk setiap kolom. (Karena pertanyaan SEPERTI warisan) Saya menghapus semua indeks dan statistik, menambahkan pencarian teks lengkap dan voa, permintaan menjadi sangat cepat.
Tampaknya indikasi mengarah ke Rencana Eksekusi yang berbeda.
Terima kasih banyak atas bantuannya!
sumber