ลำดับของคำสั่งที่มีความสำคัญใน SQL หรือไม่


121

สมมติว่าฉันมีตารางที่เรียกว่าPEOPLEมี 3 คอลัมน์ID, LastName, FirstNameไม่มีคอลัมน์ใดที่ถูกจัดทำดัชนี
LastNameมีเอกลักษณ์มากขึ้นและFirstNameมีเอกลักษณ์น้อยกว่า

หากฉันทำการค้นหา 2 ครั้ง:

select * from PEOPLE where FirstName="F" and LastName="L" 
select * from PEOPLE where LastName="L" and FirstName="F"

ความเชื่อของฉันคือข้อที่สองเร็วกว่าเนื่องจากเกณฑ์ที่ไม่ซ้ำกันมากขึ้น ( LastName) มาก่อนในwhereประโยคและบันทึกจะถูกกำจัดอย่างมีประสิทธิภาพมากขึ้น ฉันไม่คิดว่าเครื่องมือเพิ่มประสิทธิภาพจะฉลาดพอที่จะเพิ่มประสิทธิภาพ sql แรก

ความเข้าใจของฉันถูกต้องหรือไม่?


8
ไม่คำสั่งนั้นไม่สำคัญ - เครื่องมือเพิ่มประสิทธิภาพการสืบค้นใด ๆ ที่เหมาะสมจะดูคำสั่ง WHERE ทั้งหมดและหาวิธีที่มีประสิทธิภาพที่สุดในการตอบสนองข้อความค้นหานั้น
marc_s

3
คุณมีข้อสังเกตอย่างไรเมื่อคุณเรียกใช้ข้อความทั้งสองนี้ แผนการประหารชีวิตมีลักษณะอย่างไร?
Conrad Frix

3
คุณกำลังอ้างถึง RDBMS เฉพาะหรือไม่? ย่อมมีความแตกต่าง
Bjoern


คำตอบ:


101

ไม่คำสั่งนั้นไม่สำคัญ (หรืออย่างน้อยที่สุด: ไม่ควรสำคัญ)

เครื่องมือเพิ่มประสิทธิภาพการสืบค้นใด ๆ ที่เหมาะสมจะดูทุกส่วนของWHEREประโยคและค้นหาวิธีที่มีประสิทธิภาพที่สุดในการตอบสนองการสืบค้นนั้น

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

สิ่งสำคัญคือคุณมีดัชนีที่เหมาะสมสำหรับสิ่งนี้หรือไม่!

ในกรณีของ SQL Server อาจใช้ดัชนีหากคุณมี:

  • ดัชนีเปิดอยู่ (LastName, FirstName)
  • ดัชนีเปิดอยู่ (FirstName, LastName)
  • ดัชนีเพียง(LastName)หรือเพียง(FirstName)(หรือทั้งสองอย่าง)

ในทางกลับกัน - อีกครั้งสำหรับ SQL Server - หากคุณใช้SELECT *เพื่อดึงคอลัมน์ทั้งหมดจากตารางและตารางมีขนาดค่อนข้างเล็กมีโอกาสดีที่เครื่องมือเพิ่มประสิทธิภาพการสืบค้นจะทำการสแกนตาราง (หรือดัชนีคลัสเตอร์) แทนการใช้ ดัชนี (เนื่องจากการค้นหาในหน้าข้อมูลแบบเต็มเพื่อรับคอลัมน์อื่น ๆทั้งหมดมีราคาแพงเกินไปอย่างรวดเร็ว)


หากไม่มีดัชนี op อาจถูกต้องขึ้นอยู่กับข้อมูล หลักสูตรที่ทำสิ่งนี้โดยไม่ใช้ดัชนีจะเป็นการตัดสินใจที่แปลก ...
Tony Hopkinson

@TonyHopkinson: ฉันไม่คิดอย่างนั้น - แม้ว่าจะไม่มีดัชนีฉันก็สงสัยว่าจะมีความแตกต่างเลย ท้ายที่สุด: หากไม่มีดัชนีสิ่งอื่นใดนอกจากการสแกนตารางแบบเต็ม RDBMS สามารถทำได้จริงหรือ?
marc_s

2
หมายเหตุด้านที่น่าสนใจเกี่ยวกับเซิร์ฟเวอร์ SQL เห็นได้ชัดว่าลำดับของ NOT EXISTS ภายในเพรดิเคตสามารถส่งผลต่อการสร้างแผนได้จริง: bradsruminations.blogspot.com/2010/04/looking-under-hood.html
Justin Swartsel

3
สิ่งที่แปลกคือสำหรับการดำเนินการค้นหาครั้งแรกลำดับของเงื่อนไขในคำสั่ง WHERE มีความสำคัญอย่างไร! ฉันมีสองเงื่อนไขบางอย่างเช่น: WHERE T1.col_1/T2.col_2 > 10 AND T2.col_2 <> 0และได้รับDIVIDE BY 0ข้อผิดพลาด หลังจากที่ฉันเปลี่ยนคำสั่งเงื่อนไขที่การสืบค้นดำเนินการสำเร็จ จากนั้นฉันเปลี่ยนคำสั่งกลับดังนั้นฉันคาดว่าจะได้รับข้อผิดพลาดอีกครั้ง แต่คราวนี้มันได้ผลในที่สุดข้อสรุปของฉันก็คือสำหรับการเรียกใช้ครั้งแรกคำสั่งจะมีความสำคัญจนกว่าจะมีการสร้างแผนการดำเนินการหลังจากนั้นคำสั่งซื้อไม่ได้ 't matter' ทำให้เครื่องมือเพิ่มประสิทธิภาพ / แผนผู้บริหารจะดูแล
Radu Ghelieriu

1
ฉันชอบที่คุณพูดว่า "... หรืออย่างน้อยก็ไม่สำคัญ" - ฉันเห็นด้วยอย่างยิ่ง บางครั้งมันก็มีความสำคัญ แต่น่าเสียดาย ฉันเคยเห็นกรณีที่ SQL ซับซ้อนเกินกว่าที่เครื่องมือเพิ่มประสิทธิภาพจะจัดการได้และสิ่งต่างๆเช่นลำดับคอลัมน์และลำดับการเข้าร่วมตารางก็สร้างความแตกต่างได้ ขึ้นอยู่กับ RDBMS ความซับซ้อนของคำสั่ง SQL และแม้แต่การเปิดตัว SQL ที่ซับซ้อนมากอาจส่งผลให้เกิดการตัดสินใจของเครื่องมือเพิ่มประสิทธิภาพที่ไม่ดีหรือการใช้ค่าเริ่มต้นแบบฮาร์ดโค้ดในโค้ดเครื่องมือเพิ่มประสิทธิภาพ
Victor Di Leo

19

ลำดับของคำสั่ง WHERE ไม่ควรสร้างความแตกต่างในฐานข้อมูลที่สอดคล้องกับมาตรฐาน SQL ไม่รับประกันลำดับของการประเมินในฐานข้อมูลส่วนใหญ่

อย่าคิดว่า SQL ใส่ใจกับคำสั่ง สิ่งต่อไปนี้สร้างข้อผิดพลาดใน SQL Server:

select *
from INFORMATION_SCHEMA.TABLES
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0

ถ้าส่วนแรกของประโยคนี้ถูกเรียกใช้ก่อนชื่อตารางตัวเลขเท่านั้นที่จะถูกโยนเป็นจำนวนเต็ม อย่างไรก็ตามล้มเหลวโดยเป็นตัวอย่างที่ชัดเจนว่า SQL Server (เช่นเดียวกับฐานข้อมูลอื่น ๆ ) ไม่สนใจลำดับของคำสั่งในคำสั่ง WHERE


คิวรีที่ทำให้เกิดข้อผิดพลาดเกี่ยวข้องอะไรกับลำดับของการประเมินเพรดิเคต WHERE
จิม

7
@ Jim If ISNUMERIC(table_name) = 1ได้รับการประเมินก่อนจากนั้นCASTจะเรียกเฉพาะชื่อตารางตัวเลขเท่านั้น แต่เนื่องจากไม่ได้รับการประเมินก่อนCASTจึงได้รับการประเมินสำหรับชื่อตารางที่ไม่ใช่ตัวเลขเช่นกันทำให้เกิดข้อความแสดงข้อผิดพลาด
hibbelig

2
คำชี้แจงยอดเยี่ยม
neeohw

เพื่อให้แน่ใจว่าฉันได้ตรวจสอบว่าการสลับเงื่อนไขจะทำให้เซิร์ฟเวอร์ SQL จัดการกับเงื่อนไขอื่น ๆ หรือไม่ แต่ก็ล้มเหลวทั้งสองวิธี ฉันคิดว่านี่อาจหมายถึงอย่างใดอย่างหนึ่งจากสองสิ่ง: (1) มันไม่ได้รับการปรับให้เหมาะสมเท่าที่จะทำได้หรือ (2) เป็นข้อผิดพลาดในการคอมไพล์และ SQL ไม่ได้เริ่มพยายามเปรียบเทียบอะไรเลยโดยการประกันตัวเบื้องต้น ฉันเดาว่ามันไม่ใช่ 2.
Louis Somers

9

ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf

6.3.3.3 ลำดับการประเมินกฎ

...

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

คัดลอกมาจากที่นี่


2

ไม่ได้ RDBM ทั้งหมดเริ่มต้นด้วยการวิเคราะห์แบบสอบถามและปรับให้เหมาะสมโดยการจัดเรียงคำสั่ง where ของคุณใหม่

ขึ้นอยู่กับว่าคุณใช้ RDBM ใดที่คุณใช้สามารถแสดงผลลัพธ์ของการวิเคราะห์ได้ (ค้นหาคำอธิบายแผนใน oracle เป็นต้น)

เอ็ม


มันขึ้นอยู่กับดัชนี ดังนั้นจึงเป็นทางอ้อมในแง่ของเนื้อหา
Tony Hopkinson

1

คำสั่ง OP ดั้งเดิม

ความเชื่อของฉันคือข้อที่สองเร็วกว่าเนื่องจากเกณฑ์ที่ไม่ซ้ำกันมากขึ้น (LastName) มาก่อนใน> ส่วนคำสั่งที่ใดและบันทึกจะถูกกำจัดอย่างมีประสิทธิภาพมากขึ้น ฉันไม่คิดว่าเครื่องมือเพิ่มประสิทธิภาพจะ> ฉลาดพอที่จะเพิ่มประสิทธิภาพ sql แรก

ฉันเดาว่าคุณกำลังสับสนกับการเลือกลำดับของคอลัมน์ในขณะที่สร้างดัชนีซึ่งคุณต้องใส่คอลัมน์ที่เลือกมากขึ้นก่อนที่จะเลือกมากที่สุดเป็นอันดับสองเป็นต้น

BTW สำหรับแบบสอบถาม SQL Server Optimizer สองรายการข้างต้นจะไม่ทำการเพิ่มประสิทธิภาพใด ๆ แต่จะใช้แผน Trivila ตราบใดที่ต้นทุนรวมของแผนน้อยกว่าต้นทุนเกณฑ์แบบขนาน


0

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.