ผู้ประกอบการเชิงตรรกะหรือและในสภาพและคำสั่งของเงื่อนไขในที่


33

ตรวจสอบข้อความทั้งสองนี้:

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

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

ถ้าCONDITION 1เป็นTRUEจะCONDITION 2ถูกตรวจสอบ?
ถ้าCONDITION 3เป็นFALSEจะCONDITION 4ถูกตรวจสอบ?

สิ่งที่เกี่ยวกับเงื่อนไขWHERE: เครื่องยนต์ SQL Server ปรับเงื่อนไขทั้งหมดในWHEREข้อ? โปรแกรมเมอร์ควรวางเงื่อนไขในลำดับที่ถูกต้องเพื่อให้แน่ใจว่าเครื่องมือเพิ่มประสิทธิภาพ SQL Server แก้ไขได้อย่างถูกต้องหรือไม่?

เพิ่ม:

ขอบคุณแจ็คสำหรับลิงก์แปลกใจจากรหัส 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

ไม่มีการเพิ่มหารด้วยข้อยกเว้นศูนย์ในกรณีนี้

สรุป:

ถ้า C ++ / C # / VB มีการลัดวงจรทำไม SQL Server ถึงไม่มี?

เพื่อตอบคำถามนี้อย่างแท้จริงลองมาดูกันว่าทั้งสองทำงานกับเงื่อนไขอย่างไร C ++ / C # / VB ทั้งหมดมีการลัดวงจรที่กำหนดไว้ในข้อกำหนดภาษาเพื่อเพิ่มความเร็วในการเรียกใช้โค้ด เหตุใดจึงต้องประเมินสภาพ N หรือเมื่อคนแรกเป็นจริงอยู่แล้วหรือ M และเงื่อนไขเมื่อคนแรกเป็นเท็จแล้ว

พวกเราในฐานะนักพัฒนาจะต้องระวังว่า SQL Server นั้นทำงานต่าง มันเป็นระบบตามต้นทุน เพื่อให้ได้แผนการดำเนินการที่ดีที่สุดสำหรับการสืบค้นของเราตัวประมวลผลแบบสอบถามจะต้องประเมินทุก ๆ ที่เงื่อนไขและกำหนดค่าใช้จ่าย ต้นทุนเหล่านี้จะได้รับการประเมินโดยรวมเพื่อสร้างขีด จำกัด ที่ต้องต่ำกว่าขีด จำกัด ที่กำหนดไว้ของ SQL Server สำหรับแผนที่ดี ถ้าต้นทุนต่ำกว่าขีด จำกัด ที่กำหนดไว้จะมีการใช้แผนถ้าไม่ทำกระบวนการทั้งหมดซ้ำอีกครั้งด้วยต้นทุนเงื่อนไขแบบต่างๆ ค่าใช้จ่ายที่นี่เป็นได้ทั้งการสแกนหรือการค้นหาหรือการรวมหรือการรวมแฮช ฯลฯ ... ด้วยเหตุนี้การลัดวงจรตามที่มีอยู่ใน C ++ / C # / VB เป็นไปไม่ได้ คุณอาจคิดว่าการบังคับให้ใช้ดัชนีในคอลัมน์นั้นนับว่าเป็นการลัดวงจร แต่ก็ไม่เป็นเช่นนั้น มันบังคับให้ใช้ดัชนีนั้นและทำให้รายการแผนการดำเนินการสั้นลง ระบบยังคงมีต้นทุนอยู่

ในฐานะนักพัฒนาคุณต้องระวังว่า SQL Server จะไม่ทำให้เกิดการลัดวงจรเหมือนที่ทำในภาษาการเขียนโปรแกรมอื่นและไม่มีอะไรที่คุณสามารถทำได้เพื่อบังคับให้มันทำ


บล็อกคำพูดสุดท้ายอยู่ที่ไหน คุณสามารถเพิ่มการอ้างอิงได้หรือไม่?
Nick Chammas

คำตอบ:


25

ไม่มีการรับประกันใน SQL Server หากหรือในลำดับที่คำสั่งจะถูกประมวลผลในWHEREข้อ การแสดงออกเดียวที่ช่วยให้คำสั่งลัดวงจรเป็น-CASE WHENต่อไปนี้เป็นคำตอบที่ฉันโพสต์บน Stackoverflow:

SQL Server จะลัดวงจรการประเมินเงื่อนไขอย่างไร

มันทำเมื่อรู้สึกเช่นนั้น แต่ไม่ใช่ในแบบที่คุณคิดในทันที

ในฐานะที่เป็นนักพัฒนาคุณจะต้องตระหนักว่าSQL Server ไม่ได้ทำลัดวงจรเช่นนั้นจะทำในการเขียนโปรแกรมภาษาอื่น ๆ และมีอะไรที่คุณสามารถทำได้เพื่อบังคับให้มันเป็น

สำหรับรายละเอียดเพิ่มเติมให้ตรวจสอบลิงค์แรกในรายการบล็อกด้านบนซึ่งนำไปสู่บล็อกอื่น:

SQL Server ลัดวงจรหรือไม่?

คำตัดสินสุดท้าย? ฉันยังไม่มีมันจริง ๆ แต่ก็น่าจะปลอดภัยที่จะบอกว่าครั้งเดียวที่คุณสามารถมั่นใจได้ว่าการลัดวงจรที่เฉพาะเจาะจงคือเมื่อคุณแสดงเงื่อนไขหลายอย่างในกรณีที่แสดงออก ด้วยนิพจน์บูลีนมาตรฐานเครื่องมือเพิ่มประสิทธิภาพจะย้ายสิ่งต่าง ๆ ตามที่เห็นว่าเหมาะสมโดยอ้างอิงจากตารางดัชนีและข้อมูลที่คุณกำลังสอบถาม


2
เห็นได้ชัดว่ามีบางกรณีขอบ (หรือข้อผิดพลาด) ที่แม้case จะไม่ปลอดภัย
แจ็คดักลาส

1
ฉันยังแสดงให้เห็นอีกกรณีหนึ่ง (ฮ่า!) ที่มีCASEตัวแบ่ง: dba.stackexchange.com/questions/12941/…
Aaron Bertrand


0

SQL เป็นภาษาโปรแกรมเชิงประกาศ แตกต่างจากพูดว่า C ++ ซึ่งเป็นภาษาการเขียนโปรแกรมที่จำเป็น

คือคุณสามารถบอกได้ว่าคุณต้องการอะไรในผลลัพธ์สุดท้าย แต่คุณไม่สามารถบอกได้ว่าผลลัพธ์ถูกดำเนินการอย่างไรมันขึ้นอยู่กับเครื่องยนต์

วิธีเดียวที่แท้จริงในการรับประกัน "การลัดวงจร" (หรือการควบคุมการไหลอื่น ๆ) ภายในWHEREคือการใช้มุมมองที่จัดทำดัชนีตารางชั่วคราวและกลไกที่คล้ายกัน

PS คุณยังสามารถใช้คำแนะนำแผนการดำเนินการ (เพื่อ "บอกใบ้" เครื่องมือวิธีการดำเนินการค้นหาซึ่งดัชนีที่จะใช้และวิธีการใช้งาน) เพียงแค่คิดว่าฉันควรพูดถึงมันในขณะที่เราอยู่ในหัวข้อนี้ ...


-4

1) - หรือ (เงื่อนไขใดข้อหนึ่งหรือทั้งสองข้อเป็นจริง)

หากเงื่อนไข 1 เป็นจริงจากนั้นเงื่อนไข 2 จะตรวจสอบว่าเป็นจริงหรือเท็จ

- และ (เงื่อนไขทั้งสองต้องเป็นจริง)

หากเงื่อนไข 1 เป็น FALSE จะไม่มีการตรวจสอบเงื่อนไข 2


"ถ้าเงื่อนไข 1 เป็น FALSE จะไม่ตรวจสอบเงื่อนไข 2" นี่ไม่เป็นความจริง ดูคำตอบดังกล่าวข้างต้น SQL Server อาจยังคงประเมินเงื่อนไขที่ 2 ได้เนื่องจากไม่ได้ทำการประเมินการลัดวงจรในส่วนWHEREคำสั่ง
Nick Chammas

-4

วิธีเดียวที่จะควบคุมว่าเงื่อนไขในส่วนคำสั่ง WHERE คือการใช้วงเล็บเพื่อจัดกลุ่มพวกเขาเข้าด้วยกัน

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

แตกต่างจาก

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

แค่สงสัย. สองเงื่อนไขนี้แตกต่างกันอย่างไร ผลลัพธ์ที่แตกต่างประสิทธิภาพแผนการดำเนินการ ฉันคิดว่าพวกเขาจะเทียบเท่า
ypercubeᵀᴹ

ด้วยอันแรกคุณต้องตรงกับ Col1, Col4 และ Col2 หรือ Col3 ในบรรทัดที่สองเพื่อจับคู่ Col1 และ Col2 หรือคุณจำเป็นต้องจับคู่ Col3 และ Col4 แต่ Col1 และ Col4 จะไม่ต้องได้รับการประเมินร่วมกัน
mrdenny

1
ไม่คุณผิด มีลำดับความสำคัญสูงกว่าAND ORทั้งสองมีความเท่าเทียมกัน สิ่งที่คุณพูดจะเป็นจริงสำหรับWHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = xแบบสอบถาม ดูการทดสอบ SQL-Fiddle
ypercubeᵀᴹ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.