"WHERE 1 = 1" geralmente afeta o desempenho da consulta?

19

Vi recentemente a pergunta "onde 1 = 1 afirmação" ; uma construção SQL que tenho usado frequentemente na construção de SQL dinâmico, em um esforço para escrever um código mais limpo (da perspectiva da linguagem host).

De um modo geral, essa adição a uma declaração SQL afeta negativamente o desempenho da consulta? Não estou procurando uma resposta em relação a um sistema de banco de dados específico (porque eu o usei no DB2, SQL Server, MS-Access e mysql) - a menos que seja impossível responder sem entrar em detalhes.

transistor1
fonte
4
Eu acredito que qualquer otimizador seria capaz de lidar com tal condição simples e simplesmente ignorá-la plano de execução de modo final não faria contém lo em tudo
Eu também pensaria - logicamente falando, parece fazer sentido que, em geral, um otimizador de consultas simplesmente o ignore.
6
Você pode comparar o plano de execuções com e sem1=1
Luc M
4
@ Luc M: Eu fiz exatamente isso para SQLite. Acontece que não otimiza a WHILE 1=1cláusula. No entanto, parece não ter nenhum impacto detectável no tempo de execução.
dan04

Respostas:

23

Todos os principais RDBMS, tanto quanto eu sei, construíram avaliações constantes. Isso deve avaliar praticamente instantaneamente em qualquer um deles.

JNK
fonte
+1 Esse também foi o meu palpite, mas o motivo pelo qual fiz a pergunta foi obter um pouco mais de detalhes. Vou mantê-lo aberto um pouco mais para ver se recebo mais informações.
transistor1
2
Isso é ignorado. É nada a ver com o otimizador, apenas concat de onde condituon como por ligação em causa (a minha resposta também)
GBN
8

De uma perspectiva do SQL Server, se você estiver fazendo isso WHERE 1=1para permitir a passagem dinâmica de parâmetros e ignorando a avaliação de um parâmetro, sugiro que você leia alguns artigos do Erland Sommarskog, MV do SQL Server. Sua abordagem elimina a necessidade de fazer outros truques dentro do SQL dinâmico (como a WHERE Column = Columnconstrução ou o uso de uma WHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)construção). O 1 = 1 não deve causar problemas de desempenho, como o @JNK mencionou (marquei a resposta dele lá e essa é a que deve ser aceita), acho que você encontrará algumas boas dicas no artigo de Erland sobre SQL dinâmico e você também verá que ele ainda usa esse 1=1para os casos em que nenhum parâmetro é passado, mas ele os evita para parâmetros individuais que não são passados, ele simplesmente não '

Mike Walsh
fonte
Estou apenas navegando no segundo artigo (porque não estou escrevendo código para o SP1 de 2008 no momento), mas vejo que ele está usando 1 = 1 em seu código. Eu já estou familiarizado com sp_executesql, mas isso não elimina o push para usar 1 = 1, por si só. Talvez esteja faltando alguma coisa?
transistor
2
+1 - Erland é o recurso obrigatório nesse tipo de coisa.
JNK
Apenas citando o segundo link: "Nas linhas 19 a 29, componho a string SQL básica. A condição WHERE 1 = 1 na linha 29 existe para permitir que os usuários chamem o procedimento sem especificar nenhum parâmetro".
transistor1
2
Desculpe. Eu digitei errado o meu argumento. Irá editar. Não pretendi sugerir que há um problema com a construção Where 1 = 1, apenas sugerindo outras dicas para facilitar a leitura e espero evitar a abordagem de WHERE (coluna = valor ou 1 = 1) e (coluna1 = valor1 ou 1 = 1), etc. abordagem.
Mike Walsh
6

Com o MySQL, você pode verificar, executando EXPLAIN EXTENDED e, posteriormente, SHOW WARNINGS para ver a consulta real. tl; dr: fica otimizado.

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ć
fonte
1
Ótima resposta. O servidor MySQL v5.7.18 diz que 'EXTENDED' está obsoleto e será removido em uma versão futura. Do 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.foi removido no MySQL v 8.0.
mikep 9/03