«WHERE 1 = 1» a-t-il généralement un impact sur les performances des requêtes?

19

J'ai récemment vu la question "où 1 = 1 déclaration" ; une construction SQL que j'ai souvent utilisée dans la construction de SQL dynamique dans le but d'écrire du code plus propre (du point de vue du langage hôte).

De manière générale, cet ajout à un énoncé SQL affecte-t-il négativement les performances des requêtes? Je ne cherche pas de réponse concernant un système de base de données spécifique (parce que je l'ai utilisé dans DB2, SQL Server, MS-Access et mysql) - à moins qu'il soit impossible de répondre sans entrer dans les détails.

transistor1
la source
4
Je crois que tout optimiseur serait capable de gérer une condition aussi simple et de simplement l'ignorer afin que le plan d'exécution final ne le contienne pas du tout
Je le pense aussi - logiquement, il semble logique qu'en général un optimiseur de requêtes l'ignore simplement.
6
Vous pouvez comparer le plan des exécutions avec et sans1=1
Luc M
4
@ Luc M: Je l'ai fait pour SQLite. Il s'avère que cela n'optimise pas la WHILE 1=1clause. Cependant, il ne semble pas avoir d'impact décelable sur le temps d'exécution.
dan04

Réponses:

23

À ma connaissance, tous les principaux SGBDR ont intégré des évaluations constantes. Cela devrait être évalué à peu près instantanément dans chacun d'eux.

JNK
la source
+1 C'est aussi ma supposition, mais la raison pour laquelle j'ai posé la question était d'obtenir un peu plus de détails. Je vais le garder ouvert un peu plus longtemps pour voir si j'obtiens plus d'informations.
transistor1
2
Ceci est ignoré. Il n'y a rien à faire avec l'optimiseur, juste concaténer où se trouve la situation selon le lien en question (ma réponse aussi)
gbn
8

Du point de vue de SQL Server, si vous faites le WHERE 1=1pour permettre le passage dynamique des paramètres et ignorer un paramètre d'être évalué, je vous suggère de lire quelques articles de SQL Server MV Erland Sommarskog. Son approche supprime la nécessité de faire d'autres astuces à l'intérieur du SQL dynamique (comme la WHERE Column = Columnconstruction ou l'utilisation d'une WHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)construction). Le 1 = 1 ne devrait pas causer de problèmes de performance comme l'a mentionné @JNK (j'ai +1 sur sa réponse et c'est celle qui devrait être acceptée), je pense que vous trouverez de bons conseils dans l'article d'Erland autour de Dynamic SQL et vous verrez également qu'il utilise toujours celui 1=1pour les cas où aucun paramètre n'est passé mais il les évite pour les paramètres individuels qui ne sont pas passés, il ne le fait tout simplement pas

Mike Walsh
la source
Je suis juste navigation sur le deuxième article (parce que je ne suis pas à écrire du code pour 2008 SP1 pour le moment), mais je vois qu'il est utilise 1 = 1 dans son code. Je connais déjà sp_executesql, mais cela n'élimine pas la nécessité d'utiliser 1 = 1, en soi. Peut-être que je manque quelque chose?
transistor1
2
+1 - Erland est la ressource incontournable pour ce genre de choses.
JNK
Je cite simplement le deuxième lien: "Aux lignes 19 à 29, je compose la chaîne SQL de base. La condition O WH 1 = 1 à la ligne 29 est là pour permettre aux utilisateurs d'appeler la procédure sans spécifier aucun paramètre."
transistor1
2
Pardon. J'ai mal tapé mon point. Va éditer. Je ne voulais pas laisser entendre qu'il y a un problème avec la construction Where 1 = 1, suggérant simplement d'autres conseils pour la lisibilité et en évitant, espérons-le, l'approche WHERE (colonne = valeur ou 1 = 1) et (colonne1 = valeur1 ou 1 = 1), etc. approche.
Mike Walsh
6

Avec MySQL, vous pouvez vérifier, en exécutant EXPLAIN EXTENDED et plus tard AFFICHER LES AVERTISSEMENTS pour voir la requête réelle. tl; dr: il est optimisé.

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ć
la source
1
Très bonne réponse. Le serveur Btw MySQL v5.7.18 indique que «EXTENDED» est obsolète et sera supprimé dans une prochaine version. De doc mysql: 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.Il a été supprimé dans MySQL v 8.0.
mikep