Kami memiliki generator SQL yang memancarkan pernyataan kondisional SQL secara umum untuk bidang tertentu (yang untuk diskusi: kami akan beri label sebagai myField
).
Jika myField
adalah tipe NVARCHAR
, kita bisa melakukan perbandingan dari lapangan mengatakan terhadap string seperti: myField = 'foo'
.
Namun, ini tidak berfungsi untuk bidang tipe NTEXT
. Dengan demikian, kita harus melakukan perbandingan dengan gips: CAST(myField as NVARCHAR(MAX)) = 'foo'
. Ini sebenarnya akan bekerja jika myField
bertipe NVARCHAR
atau NTEXT
.
Apa kinerja yang berhasil dilakukan oleh para pemeran yang disebutkan di atas pada bidang yang sudah bertipe NVARCHAR
? Harapan saya adalah bahwa SQL Server cukup pintar untuk secara dinamis mengenali yang myField
sudah tipe NVARCHAR
(secara efektif mengubah CAST
menjadi no-op).
sumber
Jawaban:
Jika para pemeran kolom memiliki tipe dan panjang data yang sama persis dan predikat pencariannya adalah literal, hal itu memang tampaknya mengabaikannya atau memperlakukannya sebagai no-op dan melakukan indeks mencari kesetaraan.
Jika cetakan kolom adalah untuk tipe data yang sama tetapi panjang yang lebih besar dan predikat pencarian adalah string literal, hal itu menyebabkan pemindaian indeks. Ini jelas harus dihindari.
Jika para pemain kolom adalah untuk tipe data yang sama dan panjang yang sama atau lebih besar dan predikat pencarian adalah variabel lokal itu menambahkan operator skalar komputasi ke rencana eksekusi. Ini panggilan
GetRangeThroughConvert
dan output jangkauan.Rentang ini digunakan untuk melakukan pencarian indeks dan tampaknya cukup efisien
Kode Pengujian
sumber
Secara umum, ini
CAST
akan mematikan kinerja karena membatalkan penggunaan indeks seperti yang ditunjukkan contoh terakhir Martin Smith. Casting kenvarchar(max)
atau ke panjang yang berbeda berarti tipe data yang berbeda: fakta itu semuanvarchar
tidak relevan.Di atas itu semua, tipe data dari sisi kanan membandingkan juga. Jika itu adalah variabel lokal atau parameter dengan panjang yang berbeda, maka satu sisi akan secara implisit
CAST
menjadi yang terluas dari 2 tipe data (lihat prioritas tipe data ).Pada dasarnya, jika Anda memiliki jenderal
CAST
untuknvarchar(max)
itu akan bollix segalanya. Saya akan mempertimbangkan untuk memperbaiki penggunaanntext
sebelum saya menambahkanCAST
semuanya.Konversi tidak dapat ditampilkan dalam paket kueri. Lihat artikel blog Paul White
sumber
Sekedar catatan, Casting seperti ini di mana Datecreated adalah datetime
Tidak merusak kemampuan SQL untuk menggunakan indeks jika indeks ada, dan jika tidak ada, dapat mengakibatkan masuknya indeks yang hilang.
Demikian pula, ketika melakukan casting dari
int
ketinyint
ataubigint
keint
dll, fungsi cast tidak menghentikan SQL dari menggunakan indeks JIKA optimizer tahu bahwa operasi cast tidak mengubah urutan sortir dari 2 tipe data yang sebanding.Berikut adalah banyak tes yang dapat Anda jalankan dan lihat paket aktual menggunakan Adventureworks2008R2
sumber