Hat „WHERE 1 = 1“ normalerweise einen Einfluss auf die Abfrageleistung?

19

Ich habe kürzlich die Frage "where 1 = 1 statement" gesehen . Ein SQL-Konstrukt, das ich häufig beim Erstellen von dynamischem SQL verwendet habe, um saubereren Code zu schreiben (aus Sicht der Host-Sprache).

Beeinträchtigt dieser Zusatz zu einer SQL-Anweisung im Allgemeinen die Abfrageleistung? Ich suche keine Antwort in Bezug auf ein bestimmtes Datenbanksystem (weil ich es in DB2, SQL Server, MS-Access und MySQL verwendet habe) - es sei denn, es ist unmöglich zu antworten, ohne auf Einzelheiten einzugehen.

transistor1
quelle
4
Ich glaube , jeder Optimierer der Lage wäre , eine solche einfache Bedingung zu handhaben und einfach ignorieren es so endgültige Ausführungsplan würde es enthält nicht alle
Ich würde das auch denken - logischerweise scheint es sinnvoll zu sein, dass ein Abfrageoptimierer es im Allgemeinen einfach ignoriert.
6
Sie könnten den Hinrichtungsplan mit und ohne1=1
Luc M
4
@ Luc M: Ich habe genau das für SQLite gemacht. Es stellt sich heraus, dass es die WHILE 1=1Klausel nicht optimiert . Es scheint jedoch keinen erkennbaren Einfluss auf die Ausführungszeit zu haben.
Dan04

Antworten:

23

Soweit ich weiß, haben alle wichtigen RDBMS konstante Auswertungen vorgenommen. Dies sollte in jedem von ihnen ziemlich augenblicklich ausgewertet werden.

JNK
quelle
+1 Das war auch meine Vermutung, aber der Grund, warum ich die Frage gestellt habe, war, ein bisschen mehr Details zu erfahren. Ich werde es noch etwas länger offen halten, um zu sehen, ob ich noch mehr Input bekomme.
Transistor1
2
Dies wird ignoriert. Es hat nichts mit dem Optimierer zu tun, nur darauf zu achten, wo der Zustand gemäß dem fraglichen Link (auch meine Antwort) ist
gbn
8

Wenn Sie aus SQL Server-Sicht WHERE 1=1die dynamische Übergabe von Parametern zulassen und die Auswertung eines Parameters überspringen möchten, empfehle ich Ihnen, einige Artikel von SQL Server MV Erland Sommarskog zu lesen. Sein Ansatz beseitigt die Notwendigkeit, andere Tricks in dynamischem SQL auszuführen (wie das WHERE Column = ColumnKonstrukt oder die Verwendung eines WHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)Konstrukts). Das 1 = 1 sollte keine Performance-Probleme verursachen, wie @JNK erwähnt hat (ich habe seine Antwort dort +1 gegeben und das ist die, die akzeptiert werden sollte). Ich denke, Sie werden einige gute Tipps aus Erlands Artikel finden Dynamisches SQL und Sie werden sehen, dass er immer noch das 1=1für die Fälle verwendet, in denen keine Parameter übergeben werden, aber er vermeidet sie für einzelne Parameter, die nicht übergeben werden.

Mike Walsh
quelle
Ich bin gerade nur den zweiten Artikel (weil ich nicht Code für 2008 SP1 zur Zeit zu schreiben), aber ich sehe er ist mit 1 = 1 in seinem Code. Ich bin bereits mit sp_executesql vertraut, aber das beseitigt nicht den Drang, 1 = 1 an und für sich zu verwenden. Vielleicht fehlt mir etwas?
Transistor1
2
+1 - Erland ist die erste Adresse für diese Art von Dingen.
JNK
Nur ein Zitat aus dem zweiten Link: "In den Zeilen 19-29 komponiere ich die grundlegende SQL-Zeichenfolge. Die Bedingung WHERE 1 = 1 in Zeile 29 ermöglicht es den Benutzern, die Prozedur aufzurufen, ohne irgendwelche Parameter anzugeben."
Transistor1
2
Es tut uns leid. Ich habe meinen Punkt falsch geschrieben. Wird bearbeiten. Ich wollte nicht implizieren, dass es ein Problem mit dem Where 1 = 1-Konstrukt gibt. Ich schlug lediglich andere Tipps für die Lesbarkeit vor und hoffentlich vermieden, WHERE (Spalte = Wert oder 1 = 1) und (Spalte1 = Wert1 oder 1 =) zu verwenden 1) usw. Ansatz.
Mike Walsh
6

Mit MySQL können Sie EXPLAIN EXTENDED und höher SHOW WARNINGS ausführen, um die aktuelle Abfrage anzuzeigen. tl; dr: es wird weg optimiert.

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)
Dalibor Karlović
quelle
1
Gute Antwort. Btw MySQL Server v5.7.18 meldet, dass 'EXTENDED' veraltet ist und in einer zukünftigen Version entfernt wird. Von 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.Es wurde in MySQL v 8.0 entfernt.
mikep