Ini telah di-hash dan di-hash ulang. Selain tips yang saya tunjukkan di komentar dan link dan penjelasan @xQbert diposting di atas, atas permintaan berikut adalah penjelasan COALESCE vs. ISNULL menggunakan subquery. Mari kita pertimbangkan dua kueri ini, yang dalam hal hasilnya identik:
SELECT COALESCE((SELECT TOP (1) name FROM sys.objects), N'foo');
SELECT ISNULL((SELECT TOP (1) name FROM sys.objects), N'foo');
(Komentar tentang menggunakan TOP tanpa ORDER BY ke /dev/null/ terima kasih.)
Dalam kasus COALESCE, logikanya sebenarnya diperluas menjadi seperti ini:
SELECT CASE WHEN (SELECT TOP (1) ...) IS NULL
THEN (SELECT TOP (1) ...)
ELSE N'foo'
END
Dengan ISNULL, ini tidak terjadi. Ada optimasi internal yang tampaknya memastikan bahwa subquery hanya dievaluasi sekali. Saya tidak tahu apakah ada orang di luar Microsoft yang mengetahui persis bagaimana pengoptimalan ini bekerja, tetapi Anda dapat melakukannya jika Anda membandingkan rencananya. Berikut adalah rencana untuk versi COALESCE:
Dan inilah rencana untuk versi ISNULL - perhatikan betapa sederhananya (dan pemindaian hanya terjadi sekali):
Dalam kasus COALESCE pemindaian terjadi dua kali. Artinya subquery dievaluasi dua kali, meskipun tidak memberikan hasil apa pun. Jika Anda menambahkan klausa WHERE sehingga subquery menghasilkan 0 baris, Anda akan melihat perbedaan serupa - bentuk rencana mungkin berubah, tetapi Anda masih akan melihat pencarian ganda+pencarian atau pemindaian kasus COALESCE. Berikut adalah contoh yang sedikit berbeda:
SELECT COALESCE((SELECT TOP (1) name FROM sys.objects
WHERE name = N'no way this exists'), N'foo');
SELECT ISNULL((SELECT TOP (1) name FROM sys.objects
WHERE name = N'no way this exists'), N'foo');
Rencana untuk versi COALESCE kali ini - sekali lagi Anda dapat melihat seluruh cabang yang mewakili subquery diulang kata demi kata:
Dan sekali lagi rencana yang jauh lebih sederhana, melakukan kira-kira setengah pekerjaan, menggunakan ISNULL:
Anda juga dapat melihat pertanyaan ini di dba.se untuk diskusi lebih lanjut:
Saran saya adalah ini (dan Anda dapat melihat alasan saya mengapa di tip dan pertanyaan di atas):percaya tetapi verifikasi. Saya selalu menggunakan COALESCE (karena ini adalah standar ANSI, mendukung lebih dari dua argumen, dan tidak melakukan hal-hal miring dengan prioritas tipe data) kecuali Saya tahu saya menggunakan subquery sebagai salah satu ekspresi (yang saya tidak ingat pernah melakukannya di luar pekerjaan teoretis seperti ini) atau saya mengalami masalah kinerja nyata dan hanya ingin membandingkan untuk melihat apakah COALESCE vs. ISNULL memiliki perbedaan kinerja yang substansial (yang di luar kasus subquery, saya belum menemukan). Karena saya hampir selalu menggunakan COALESCE dengan argumen seperti tipe data, saya jarang harus melakukan pengujian apa pun selain melihat kembali apa yang telah saya katakan sebelumnya (saya juga penulis artikel aspfaq yang ditunjukkan xQbert , 7 tahun yang lalu).