it-swarm-id.com

Operator logis OR DAN dalam kondisi dan urutan kondisi di WHERE

Mari kita periksa dua pernyataan ini:

IF (CONDITION 1) OR (CONDITION 2)
...

IF (CONDITION 3) AND (CONDITION 4)
...

Jika CONDITION 1 adalah TRUE, akan CONDITION 2 diperiksa?
Jika CONDITION 3 adalah FALSE, akan CONDITION 4 diperiksa?

Bagaimana dengan kondisi pada WHERE: apakah mesin SQL Server mengoptimalkan semua kondisi dalam klausa WHERE? Haruskah programmer menempatkan kondisi dalam kanan untuk memastikan bahwa pengoptimal SQL Server menyelesaikannya dalam kanan cara?

TAMBAH:

Terima kasih kepada Jack untuk tautannya, kejutan dari kode t-sql:

IF  1/0 = 1 OR 1 = 1
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result


IF  1/0 = 1 AND 1 = 0
      SELECT 'True' AS result
ELSE
      SELECT 'False' AS result

Tidak ada peningkatan pengecualian Bagi dengan nol dalam kasus ini.

KESIMPULAN:

Jika C++/C #/VB memiliki hubungan arus pendek mengapa SQL Server tidak dapat memilikinya?

Untuk benar-benar menjawab ini, mari kita lihat bagaimana keduanya bekerja dengan kondisi. C++/C #/VB semuanya memiliki hubungan arus pendek yang ditentukan dalam spesifikasi bahasa untuk mempercepat eksekusi kode. Mengapa repot-repot mengevaluasi N OR kondisi ketika yang pertama sudah benar atau M DAN kondisi ketika yang pertama sudah salah.

Kami sebagai pengembang harus menyadari bahwa SQL Server bekerja secara berbeda. Ini adalah sistem berbasis biaya. Untuk mendapatkan rencana eksekusi optimal untuk kueri kami, prosesor kueri harus mengevaluasi setiap kondisi tempat dan menetapkan biayanya. Biaya-biaya ini kemudian dievaluasi secara keseluruhan untuk membentuk ambang batas yang harus lebih rendah dari ambang batas yang ditetapkan SQL Server untuk rencana yang baik. Jika biayanya lebih rendah dari ambang yang ditentukan, rencana itu digunakan, jika tidak seluruh proses diulangi lagi dengan campuran biaya kondisi yang berbeda. Biaya di sini adalah pemindaian atau pencarian atau gabungan atau hash bergabung dll ... Karena ini hubungan arus pendek seperti yang tersedia di C++/C #/VB tidak mungkin. Anda mungkin berpikir bahwa memaksakan penggunaan indeks pada kolom dianggap sebagai hubungan arus pendek tetapi tidak. Itu hanya memaksa penggunaan indeks itu dan dengan itu mempersingkat daftar kemungkinan rencana eksekusi. Sistem ini masih berbasis biaya.

Sebagai pengembang Anda harus menyadari bahwa SQL Server tidak melakukan hubungan arus pendek seperti yang dilakukan dalam bahasa pemrograman lain dan tidak ada yang dapat Anda lakukan untuk memaksanya.

35
garik

Tidak ada jaminan di SQL Server jika atau dalam urutan mana pernyataan akan diproses dalam klausa WHERE. Ekspresi tunggal yang memungkinkan hubungan arus pendek pernyataan adalah CASE-WHEN. Berikut ini dari jawaban yang saya posting di Stackoverflow:

Bagaimana sirkuit pendek SQL Server evaluasi kondisi WHERE

Itu terjadi ketika rasanya seperti itu, tetapi tidak dengan cara yang langsung Anda pikirkan.

Sebagai pengembang Anda harus menyadari bahwa SQL Server tidak melakukan hubungan arus pendek seperti yang dilakukan dalam bahasa pemrograman lain dan tidak ada yang dapat Anda lakukan untuk memaksanya .

Untuk perincian lebih lanjut, periksa tautan pertama di entri blog di atas, yang mengarah ke blog lain:

Apakah SQL Server Short-Circuit?

Putusan akhir? Yah, saya belum benar-benar memilikinya, tetapi mungkin aman untuk mengatakan bahwa satu-satunya waktu Anda dapat memastikan korsleting spesifik adalah ketika Anda mengekspresikan beberapa kondisi KAPAN dalam ekspresi KASUS. . Dengan ekspresi boolean standar, optimizer akan memindahkan segala sesuatunya sesuai dengan tabel, indeks dan data yang Anda tanyakan.

27
MicSim

Dalam T-SQL, pernyataan IF dapat mengalami hubungan pendek, tetapi Anda tidak dapat mengandalkannya untuk mengevaluasi ekspresi secara berurutan

SQL adalah bahasa pemrograman deklaratif . Tidak seperti, katakanlah, C++ yang merupakan bahasa pemrograman imperatif .

Yaitu. Anda dapat mengatakannya apa yang Anda inginkan di hasil akhir, tetapi Anda tidak dapat mendikte bagaimana hasilnya sedang dieksekusi, semuanya tergantung pada mesin.

Satu-satunya cara yang benar untuk menjamin "hubungan arus pendek" (atau aliran kontrol lainnya ) di dalam WHERE adalah menggunakan tampilan yang diindeks, sementara tabel dan mekanisme serupa.

PS. Anda juga dapat menggunakan petunjuk rencana eksekusi (untuk "memberi petunjuk" pada mesin bagaimana menjalankan kueri, indeks mana yang digunakan dan BAGAIMANA menggunakannya), saya pikir saya harus menyebutkannya, sementara kita sedang membahas topik ini ...

0
jitbit