ดีไม่ดีหรือไม่แยแส: WHERE 1 = 1


14

เมื่อให้คำถามนี้กับ reddit ฉันได้ล้างคิวรีเพื่อชี้ให้เห็นว่าปัญหาอยู่ที่ไหนในเคียวรี ฉันใช้เครื่องหมายจุลภาคก่อนและWHERE 1=1ทำให้การสืบค้นแก้ไขง่ายขึ้นดังนั้นโดยทั่วไปแล้วข้อความค้นหาของฉันจะเป็นดังนี้:

SELECT 
     C.CompanyName
    ,O.ShippedDate
    ,OD.UnitPrice
    ,P.ProductName
FROM 
               Customers       as C
    INNER JOIN Orders          as O  ON C.CustomerID = O.CustomerID
    INNER JOIN [Order Details] as OD ON O.OrderID    = OD.OrderID
    INNER JOIN Products        as P  ON P.ProductID  = OD.ProductID
Where 1=1
--  AND O.ShippedDate Between '4/1/2008' And '4/30/2008'
    And P.productname = 'TOFU'
Order By C.CompanyName

ใครบางคนโดยทั่วไปกล่าวว่า1 = 1 โดยทั่วไปคือขี้เกียจและไม่ดีสำหรับการทำงาน

เนื่องจากฉันไม่ต้องการ "เพิ่มประสิทธิภาพก่อนกำหนด" - ฉันต้องการปฏิบัติตามแนวทางปฏิบัติที่ดี ฉันเคยดูที่แผนคิวรีมาก่อน แต่โดยทั่วไปแล้วจะพบว่าฉันสามารถเพิ่มดัชนี (หรือปรับ) ดัชนีใดเพื่อให้คิวรีทำงานได้เร็วขึ้น

คำถามนั้นจริง ๆ ... Where 1=1ทำให้สิ่งเลวร้ายเกิดขึ้นหรือไม่ และถ้าเป็นเช่นนั้นฉันจะบอกได้อย่างไร?

การแก้ไขเล็กน้อย: ฉันมักจะ 'สันนิษฐาน' เช่นกันว่า1=1จะได้รับการปรับปรุงให้ดีที่สุดหรืออย่างน้อยที่สุดก็เล็กน้อย อย่าเจ็บคำถามมนต์เช่น "Goto's are Evil" หรือ "Premature Optimization ... " หรือข้อเท็จจริงอื่น ๆ ไม่แน่ใจว่า1=1 ANDจะมีผลกับแผนคิวรีจริงหรือไม่ สิ่งที่เกี่ยวกับในแบบสอบถามย่อย? CTE หรือไม่? ขั้นตอน?

ฉันไม่ใช่คนที่จะปรับให้เหมาะสมเว้นแต่จะจำเป็น ... แต่ถ้าฉันทำสิ่งที่ "เลวร้าย" จริง ๆ แล้วฉันต้องการลดผลกระทบหรือเปลี่ยนแปลงตามความเหมาะสม


2
ไม่มันจะไม่ นอกเหนือจากไม่กี่วินาทีสำหรับเครื่องมือเพิ่มประสิทธิภาพในการลบเงื่อนไขซ้ำซ้อน คุณควรมุ่งเน้นไปที่ตัวอักษรวันที่ของคุณไม่ชัดเจน
ypercubeᵀᴹ

ตามที่ @percube กล่าวว่ามันไม่ได้สร้างความแตกต่าง เพิ่มประสิทธิภาพแบบสอบถามจะต้องมีชิ้นส่วนของ **** สำหรับสิ่งที่ดังกล่าวเพื่อสร้างความแตกต่างใด ๆ ;)
Philᵀᴹ

4
อย่าเชื่อทุกสิ่งที่คุณอ่านบน reddit โปรด.
Aaron Bertrand

1
@AaronBertrand ฉันเอาทุกอย่างไปด้วยเม็ดเกลือจนกว่าฉันจะได้สัมผัสกับมันโดยตรง ฉันจะยังคงใช้คำถามที่ฟังดูมีเหตุผลและดูว่ามีความจริงใด ๆ หรือไม่โดยเฉพาะอย่างยิ่งเมื่อมันส่งผลกระทบต่องานประจำวันของฉัน
WernerCD

4
มีเม็ดเกลือจากนั้นมีปริมาณเกลือของมหาสมุทรทั้งหมดที่ถูกทิ้งไว้บนอาคารสำนักงานของคุณ: P
Philᵀᴹ

คำตอบ:


13

เซิร์ฟเวอร์ SQL parserเครื่องมือเพิ่มประสิทธิภาพมีคุณสมบัติที่เรียกว่า "การพับอย่างต่อเนื่อง" ซึ่งจะกำจัดนิพจน์ที่ซ้ำซ้อนจากการสืบค้น
หากคุณดูที่แผนปฏิบัติการไม่มีที่ไหนในภาคแสดงคุณจะเห็นว่านิพจน์นั้นปรากฏขึ้น นี่ก็หมายความว่าการพับแบบคงที่จะดำเนินการในเวลารวบรวมด้วยเหตุผลนี้และเหตุผลอื่น ๆ และไม่มีผลต่อประสิทธิภาพการค้นหา

ดูการประเมินการพับและการแสดงออกอย่างต่อเนื่องในระหว่างการประมาณค่า Cardinalityสำหรับข้อมูลเพิ่มเติม


มันอาจจะถูกรวบรวมเพราะมันเป็นรูปแบบที่รู้จักกันดีในการต่อเรียงฟิลด์
jcolebrand

ไม่มันถูกเรียบเรียงเพราะมันไม่ธรรมดา มันจะทำงานในลักษณะเดียวกันกับ 2736 = 2736 ซึ่งไม่เหมือนกับ 1 = 1 เช่นเดียวกับความขัดแย้ง ในกรณีนั้นคุณสมบัตินี้เรียกว่า "การตรวจจับความขัดแย้ง"
spaghettidba

ส่วนใดของ "รูปแบบที่รู้จัก" หมายถึง "ต้องเป็น 1 = 1"
jcolebrand

9

การเพิ่มภาคที่ซ้ำซ้อนสามารถสร้างความแตกต่างใน SQL Server

ในแผนปฏิบัติการด้านล่างสังเกตเห็นว่า@1ในแผนแรกเทียบกับตัวอักษร'foo'ในแผนสอง

ป้อนคำอธิบายรูปภาพที่นี่

สิ่งนี้บ่งชี้ว่า SQL Server พิจารณาแบบสอบถามแรกสำหรับการสร้างพารามิเตอร์อย่างง่ายเพื่อส่งเสริมการใช้แผนปฏิบัติการซ้ำ - อย่างไรก็ตามการเปรียบเทียบค่าคงที่สองค่าจะป้องกันไม่ให้สิ่งนี้เกิดขึ้นในกรณีที่สอง

รายการเงื่อนไขที่ป้องกันการปรับพารามิเตอร์แบบง่าย (ก่อนหน้านี้รู้จักกันในชื่อการกำหนดพารามิเตอร์อัตโนมัติ) สามารถดูได้ในภาคผนวก A ของเอกสารทางเทคนิคของแผนการแคช Microsoft:

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


4

ใน RDBMS ที่ทันสมัย ​​(รวมถึง Oracle, Microsoft SQL Server และ PostgreSQL - ฉันแน่ใจเกี่ยวกับสิ่งเหล่านี้) สิ่งนี้จะไม่มีผลต่อประสิทธิภาพ

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

SELECT 1 FROM empty_table; -- run this 10 000 times.

SELECT 1 FROM empty_table WHERE 1=1; -- run this 10 000 times and compare.

สำหรับฉันใน PostgreSQL 9.0 จะมองเห็นได้ด้วยการวนซ้ำ 10,000 ครั้งเท่านั้น:

filip@srv:~$ pgquerybench.pl -h /var/run/postgresql/ -q "select 1 from never where 1=1" -q "select 1 from never" -i 10000
Iterations: 10000
Query:   select 1 from never where 1=1
Total:   2.952 s
Average: 0.295 ms
Query:   select 1 from never
Total:   2.850 s
Average: 0.285 ms

0

นี่อาจเป็น "ปัญหา" สำหรับ Oracle เมื่อคุณใช้พารามิเตอร์ฐานข้อมูล cursor_sharing เมื่อสิ่งนี้ถูกตั้งค่าเป็น "บังคับ" มันจะแก้ไขคำสั่ง SQL ทั้งหมด "ค่าคงที่" ทั้งหมดในแบบสอบถามจะถูกแทนที่ด้วยตัวแปรผูก (เช่น 1 =>: SYS_0)

ตัวเลือกนี้ได้รับการแนะนำให้รู้จักกับนักพัฒนาที่ขี้เกียจ ในทางกลับกันก็อาจเป็นอันตรายต่อนักพัฒนาขี้เกียจอื่น ๆ แต่ความเสี่ยงไม่สูงเกินไป ตั้งแต่ 11 กรัมมันมีคุณสมบัติการแอบดูตัวแปร


คุณช่วยอธิบายสิ่งที่"ตั้งแต่ 11g มันมีคุณสมบัติการผูกตัวแปรมอง" หมายถึง?
ypercubeᵀᴹ

@ypercube "การผูกตัวแปรมอง" หมายความว่าเครื่องมือเพิ่มประสิทธิภาพจะสังเกตเห็นค่าจริงของตัวแปรผูกและใช้สถิติข้อมูลเพื่อประเมินอีกครั้งและอาจสร้างแผนปฏิบัติการแบบสอบถามอีกครั้ง ฉันสงสัยการแอบดูจะมีผลกระทบใด ๆ กับโครงสร้างที่กำลังกล่าวถึงแม้ว่าจะไม่ได้ขึ้นอยู่กับสถิติข้อมูล
mustaccio
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.