“ WHERE 1 = 1” มักส่งผลกระทบต่อประสิทธิภาพการค้นหาหรือไม่


19

ฉันเพิ่งเห็นคำถาม"ที่ 1 = 1 คำสั่ง" ; สร้าง SQL ฉันได้ใช้บ่อยในการสร้าง SQL แบบไดนามิกในความพยายามที่จะเขียนรหัสสะอาด (จากมุมมองของภาษาโฮสต์)

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


4
ฉันเชื่อว่าเครื่องมือเพิ่มประสิทธิภาพใด ๆ จะสามารถจัดการกับสภาพที่เรียบง่ายเช่นนี้และเพียงละเว้นมันดังนั้นแผนการดำเนินการขั้นสุดท้ายจะไม่รวมอยู่ในนั้น

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

6
คุณสามารถเปรียบเทียบแผนการดำเนินการที่มีและไม่มี1=1
Luc M

4
@ Lucuc M: ฉันทำแค่นั้นสำหรับ SQLite กลับกลายเป็นว่ามันไม่ได้เพิ่มประสิทธิภาพWHILE 1=1ข้อประโยค อย่างไรก็ตามดูเหมือนว่าจะไม่มีผลกระทบที่ตรวจพบได้ในเวลาดำเนินการ
dan04

คำตอบ:


23

RDBMS ที่สำคัญทั้งหมดเท่าที่ฉันรู้ได้สร้างขึ้นในการประเมินผลอย่างต่อเนื่อง สิ่งนี้ควรประเมินสิ่งใดสิ่งหนึ่งในทันที


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

2
สิ่งนี้จะถูกละเว้น มันเป็นอะไรที่จะมีเพิ่มประสิทธิภาพเพียง concat ของที่ condituon ตามการเชื่อมโยงในคำถาม (คำตอบของฉันเกินไป)
GBN

8

จากมุมมอง SQL Server หากคุณกำลังทำWHERE 1=1เพื่ออนุญาตให้ผ่านพารามิเตอร์แบบไดนามิกและข้ามพารามิเตอร์จากการประเมินฉันขอแนะนำให้คุณอ่านบทความสองสามบทจาก SQL Server MV Erland Sommarskog วิธีการของเขาขจัดความต้องการที่จะทำเทคนิคอื่น ๆ ภายใน SQL แบบไดนามิก (เช่นการWHERE Column = Columnสร้างหรือใช้การWHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)สร้าง) The 1 = 1 ไม่ควรทำให้เกิดปัญหาด้านประสิทธิภาพตามที่ @JNK พูดถึง (ฉันได้ +1 คำตอบของเขาที่นั่นและนั่นเป็นคำตอบที่ควรได้รับการยอมรับ) ฉันคิดว่าคุณจะพบเคล็ดลับดีๆจากบทความของ Erland Dynamic SQL และคุณจะเห็นว่าเขายังคงใช้ตัวพิมพ์1=1ในกรณีที่ไม่มีการส่งพารามิเตอร์ แต่เขาหลีกเลี่ยงสำหรับพารามิเตอร์แต่ละตัวที่ไม่ผ่านเขาก็ไม่ใช้ '


ฉันแค่เรียกดูบทความที่สอง (เพราะผมไม่ได้เขียนโค้ดสำหรับ 2008 SP1 ในขณะนี้) แต่ฉันเห็นเขาจะใช้ 1 = 1 ในรหัสของเขา ฉันคุ้นเคยกับ sp_executesql แล้ว แต่นั่นไม่ได้ช่วยลดการใช้ 1 = 1 ในและของตัวเอง บางทีฉันอาจจะหายไปบางอย่าง
ทรานซิสเตอร์ 1

2
+1 - Erland เป็นทรัพยากรที่มุ่งสู่สิ่งนี้
JNK

เพียงแค่อ้างจากลิงก์ที่สอง: "ในบรรทัดที่ 19-29 ฉันเขียนสตริง SQL พื้นฐานเงื่อนไขที่ 1 = 1 ในบรรทัดที่ 29 จะมีเพื่อให้ผู้ใช้สามารถเรียกขั้นตอนโดยไม่ต้องระบุพารามิเตอร์ใด ๆ เลย"
ทรานซิสเตอร์ 1

2
ขอโทษ ฉันพิมพ์ผิดจุดของฉัน จะแก้ไข ฉันไม่ได้หมายความว่ามีปัญหากับโครงสร้าง Where 1 = 1 เพียงแค่แนะนำเคล็ดลับอื่น ๆ สำหรับการอ่านและหวังว่าจะหลีกเลี่ยงวิธีการของ WHERE (column = value หรือ 1 = 1) และ (column1 = value1 หรือ 1 = 1) วิธีการอื่น ๆ
Mike Walsh

6

ด้วย MySQL คุณสามารถตรวจสอบเรียกใช้ขยายส่วนขยายและภายหลังแสดงคำเตือนเพื่อดูคิวรีที่แท้จริง tl; dr: มันได้รับการปรับให้เหมาะสม

mysql> use test
Database changed
mysql> create table test1(val int);
Query OK, 0 rows affected (0.19 sec)

mysql> explain extended select * from test1 where val > 11 and 1 = 1;
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test1 | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+--------------------------------------------------------------------------------------------+
| Level | Code | Message                                                                                    |
+-------+------+--------------------------------------------------------------------------------------------+
| Note  | 1003 | select `test`.`test1`.`val` AS `val` from `test`.`test1` where (`test`.`test1`.`val` > 11) |
+-------+------+--------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

1
คำตอบที่ดี Btw MySQL server v5.7.18 บอกว่า 'EXTENDED' เลิกใช้แล้วและจะถูกลบออกในอนาคต จาก mysql doc: In older MySQL releases, extended information was produced using EXPLAIN EXTENDED. That syntax is still recognized for backward compatibility but extended output is now enabled by default, so the EXTENDED keyword is superfluous and deprecated. Its use results in a warning, and it will be removed from EXPLAIN syntax in a future MySQL release.มันถูกลบใน MySQL v 8.0
mikep
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.