¿"WHERE 1 = 1" generalmente tiene un impacto en el rendimiento de la consulta?

19

Recientemente vi la pregunta "donde 1 = 1 declaración" ; Una construcción SQL que he usado a menudo para construir SQL dinámico en un esfuerzo por escribir código más limpio (desde la perspectiva del lenguaje anfitrión).

En términos generales, ¿esta adición a una declaración SQL afecta negativamente el rendimiento de la consulta? No estoy buscando una respuesta con respecto a un sistema de base de datos específico (porque lo he usado en DB2, SQL Server, MS-Access y mysql), a menos que sea imposible responder sin entrar en detalles.

transistor1
fuente
44
Creo que cualquier optimizador sería capaz de manejar tal condición simple y sencillamente ignorarlo plan de ejecución de manera final no contiene en absoluto
Yo también lo pensaría, lógicamente hablando, parece tener sentido que, en general, un optimizador de consultas simplemente lo ignore.
66
Se podría comparar las ejecuciones planean satisfechas con y sin1=1
Luc M
44
@Luc M: Hice exactamente eso para SQLite. Resulta que no optimiza la WHILE 1=1cláusula. Sin embargo, no parece tener ningún impacto detectable en el tiempo de ejecución.
dan04

Respuestas:

23

Todos los principales RDBMS, que yo sepa, han incorporado evaluaciones constantes. Esto debería evaluarse casi instantáneamente en cualquiera de ellos.

JNK
fuente
+1 Esta también ha sido mi suposición, pero la razón por la que hice la pregunta fue para obtener un poco más de detalle. Voy a mantenerlo abierto un poco más para ver si obtengo más información.
transistor1
2
Esto es ignorado. Es nada que ver con el optimizador, justo donde concat de condituon según enlace en cuestión (mi respuesta también)
GBN
8

Desde una perspectiva de SQL Server, si está haciendo lo WHERE 1=1posible para permitir el paso dinámico de parámetros y omitir la evaluación de un parámetro, le sugiero que lea un par de artículos del MV de SQL Server Erland Sommarskog. Su enfoque elimina la necesidad de hacer otros trucos dentro del SQL dinámico (como la WHERE Column = Columnconstrucción o el uso de una WHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)construcción). El 1 = 1 no debería causar problemas de rendimiento como mencionó @JNK (he hecho +1 en su respuesta allí y esa es la que debería aceptarse), creo que encontrará algunos buenos consejos del artículo de Erland sobre SQL dinámico y también verá que todavía usa el 1=1de los casos en los que no se pasan parámetros, pero los evita para los parámetros individuales que no se pasan, simplemente no

Mike Walsh
fuente
Solo estoy leyendo el segundo artículo (porque no estoy escribiendo código para 2008 SP1 en este momento), pero veo que está usando 1 = 1 en su código. Ya estoy familiarizado con sp_executesql, pero eso no elimina el impulso de usar 1 = 1, en sí mismo. Tal vez me estoy perdiendo algo?
transistor1
2
+1: Erland es el recurso de referencia para este tipo de cosas.
JNK
Simplemente citando el segundo enlace: "En las líneas 19-29, compongo la cadena SQL básica. La condición DONDE 1 = 1 en la línea 29 está ahí para permitir a los usuarios llamar al procedimiento sin especificar ningún parámetro".
transistor1
2
Lo siento. Escribí mal mi punto. Se editará No quise decir que haya un problema con el constructo Where 1 = 1, solo sugiriendo otros consejos para la legibilidad y con suerte evitando el enfoque de WHERE (columna = valor o 1 = 1) y (columna1 = valor1 o 1 = 1), etc. enfoque.
Mike Walsh el
6

Con MySQL, puede verificar, ejecutando EXPLAIN EXTENDED y luego SHOW WARNINGS para ver la consulta real. tl; dr: se optimiza lejos.

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ć
fuente
1
Gran respuesta. Por cierto, el servidor MySQL v5.7.18 dice que 'EXTENDIDO' está en desuso y se eliminará en una versión futura. De 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.se eliminó en MySQL v 8.0.
mikep