Operator logis ATAU DAN dalam kondisi dan urutan kondisi di MANA

33

Mari kita periksa dua pernyataan ini:

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

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

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

Bagaimana dengan kondisi pada WHERE: apakah mesin SQL Server mengoptimalkan semua kondisi dalam WHEREklausa? Haruskah programmer menempatkan kondisi dalam urutan yang benar untuk memastikan bahwa pengoptimal SQL Server menyelesaikannya dengan cara yang benar ?

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 menaikkan Divide dengan pengecualian 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 ATAU kondisi saat 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 yang optimal untuk kueri kami, prosesor kueri harus mengevaluasi setiap kondisi 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 maka rencana tersebut 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 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.

garik
sumber
Dari mana blok kutipan terakhir berasal? Bisakah Anda menambahkan referensi?
Nick Chammas

Jawaban:

25

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

Bagaimana hubungan pendek SQL Server WHERE evaluasi kondisi

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, pengoptimal akan bergerak sesuai keinginan berdasarkan tabel, indeks, dan data yang Anda tanyakan.

MicSim
sumber
2
Rupanya ada beberapa kasus tepi (atau bug) di mana bahkan case tidak aman
Jack Douglas
1
Saya juga mendemonstrasikan kasus lain (ha!) Di mana CASEistirahat: dba.stackexchange.com/questions/12941/…
Aaron Bertrand
0

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

Yaitu Anda dapat mengatakan apa yang Anda inginkan pada hasil akhir, tetapi Anda tidak dapat menentukan bagaimana hasilnya dijalankan, semuanya tergantung pada mesin.

Satu-satunya cara yang benar untuk menjamin "hubungan arus pendek" (atau aliran kontrol lainnya ) di dalamnya WHEREadalah dengan menggunakan tampilan yang diindeks, tabel sementara 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 ...

jitbit
sumber
-4

1) - ATAU (salah satu atau kedua kondisi akan BENAR)

jika kondisi 1 BENAR maka kondisi 2 juga akan diperiksa itu bisa BENAR atau SALAH

--AND (kedua kondisi harus BENAR)

jika kondisi 1 SALAH maka kondisi 2 tidak akan diperiksa

Ranjith Kumar
sumber
"jika kondisi 1 SALAH maka kondisi 2 tidak akan diperiksa" Ini tidak benar. Lihat jawaban di atas . SQL Server masih dapat mengevaluasi kondisi 2 karena tidak melakukan evaluasi hubung singkat dalam WHEREklausa.
Nick Chammas
-4

Satu-satunya cara untuk mengontrol bagaimana kondisi dalam klausa WHERE adalah dengan menggunakan tanda kurung untuk mengelompokkannya.

WHERE Col1 = 'Something' AND Col2 = 'Something' OR Col3 = 'Something' and Col4 = 'Something'

sangat berbeda dari

WHERE (Col1 = 'Something' AND Col2 = 'Something') OR (Col3 = 'Something' and Col4 = 'Something')
mrdenny
sumber
Hanya penasaran. Bagaimana kedua kondisi ini berbeda? Hasil yang berbeda, kinerja, rencana pelaksanaan? Saya pikir mereka akan setara.
ypercubeᵀᴹ
Dengan yang pertama Anda harus mencocokkan Col1, Col4 dan Col2 atau Col3. Di baris kedua untuk mencocokkan Col1 dan Col2 atau Anda harus mencocokkan Col3 dan Col4 tetapi Col1 dan Col4 tidak perlu keduanya dievaluasi bersama.
mrdenny
1
Tidak, kamu salah. ANDmemiliki prioritas lebih tinggi dari OR. Keduanya setara. Apa yang Anda katakan akan benar untuk WHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = xkueri. Lihat uji SQL-Fiddle
ypercubeᵀᴹ