"WHERE 1 = 1" di solito ha un impatto sulle prestazioni della query?


19

Di recente ho visto la domanda "dove 1 = 1 istruzione" ; un costrutto SQL che ho usato spesso nella costruzione di SQL dinamico nel tentativo di scrivere codice più pulito (dal punto di vista della lingua host).

In generale, questa aggiunta a una dichiarazione SQL influisce negativamente sulle prestazioni della query? Non sto cercando una risposta per quanto riguarda un sistema di database specifico (perché l'ho usato in DB2, SQL Server, MS-Access e mysql) - a meno che non sia impossibile rispondere senza entrare nei dettagli.


4
Credo che qualsiasi ottimizzatore sarebbe in grado di gestire una condizione così semplice e semplicemente ignorarla in modo che il piano di esecuzione finale non lo contenga affatto

Lo penserei anche io, logicamente parlando, sembra logico che in generale un Query Optimizer semplicemente lo ignorerebbe.

6
Puoi confrontare il piano delle esecuzioni con e senza1=1
Luc M

4
@Luc M: l'ho fatto proprio per SQLite. Si scopre che non ottimizza la WHILE 1=1clausola. Tuttavia, non sembra avere alcun impatto rilevabile sui tempi di esecuzione.
dan04,

Risposte:


23

Tutti i principali RDBMS, per quanto ne so, hanno costruito valutazioni costanti. Questo dovrebbe valutare praticamente istantaneamente in ognuno di essi.


+1 Questa è stata anche la mia ipotesi, ma il motivo per cui ho posto la domanda è stato quello di ottenere un po 'più di dettagli. Ho intenzione di tenerlo aperto un po 'più a lungo per vedere se ricevo ulteriori input.
transistor1

2
Questo è ignorato. Non c'è niente da fare con l'ottimizzatore, basta concedersi di dove condizionale secondo il link in questione (anche la mia risposta)
gbn

8

Dal punto di vista di SQL Server, se si sta facendo ciò WHERE 1=1per consentire il passaggio dinamico di parametri e saltare un parametro dalla valutazione, suggerirei di leggere un paio di articoli da Erland Sommarskog di SQL Server. Il suo approccio elimina la necessità di fare altri trucchi all'interno di SQL dinamico (come il WHERE Column = Columncostrutto o l'utilizzo di un WHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)costrutto). Il 1 = 1 non dovrebbe causare problemi di prestazioni come menzionato da @JNK (ho fatto +1 sulla sua risposta lì e questa è quella che dovrebbe essere accettata), penso che troverai alcuni buoni consigli dall'articolo di Erland in giro SQL dinamico e vedrai anche che usa ancora quello 1=1per i casi in cui non vengono passati parametri ma li evita per i singoli parametri che non vengono passati, semplicemente non lo fa


Sto solo sfogliando il secondo articolo (perché al momento non sto scrivendo codice per 2008 SP1), ma vedo che sta usando 1 = 1 nel suo codice. Conosco già sp_executesql, ma ciò non elimina la spinta a usare 1 = 1, in sé e per sé. Forse mi manca qualcosa?
transistor1

2
+1 - Erland è la risorsa di riferimento per questo genere di cose.
JNK,

Citando solo il secondo link: "Nelle righe 19-29, compongo la stringa SQL di base. La condizione WHERE 1 = 1 nella riga 29 è lì per consentire agli utenti di chiamare la procedura senza specificare alcun parametro".
transistor1

2
Scusa. Ho sbagliato a digitare il mio punto. Modifica. Non intendevo implicare che ci fosse un problema con il costrutto Where 1 = 1, suggerendo solo altri suggerimenti per la leggibilità ed eventualmente speriamo di evitare l'approccio di WHERE (colonna = valore o 1 = 1) e (colonna1 = valore1 o 1 = 1), approccio ecc.
Mike Walsh,

6

Con MySQL, puoi controllare, eseguendo EXPLAIN EXTENDED e successivamente SHOW WARNINGS per vedere la query effettiva. tl; dr: viene ottimizzato via.

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
Bella risposta. A proposito del server MySQL v5.7.18, "EXTENDED" è obsoleto e verrà rimosso in una versione futura. Da 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.stato rimosso in MySQL v 8.0.
mikep
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.