Влияет ли «ГДЕ 1 = 1» на производительность запросов?

19

Я недавно видел вопрос "где 1 = 1 утверждение" ; конструкция SQL, которую я часто использовал при построении динамического SQL, чтобы написать более чистый код (с точки зрения основного языка).

Вообще говоря, влияет ли это дополнение к SQL-статистике на производительность запросов? Я не ищу ответа относительно конкретной системы баз данных (потому что я использовал ее в DB2, SQL Server, MS-Access и mysql) - если только это невозможно, не вдаваясь в подробности.

transistor1
источник
4
Я полагаю, что любой оптимизатор сможет справиться с таким простым условием и просто проигнорирует его, чтобы окончательный план выполнения не содержал его вообще
Я бы тоже так подумал - логически говоря, кажется, имеет смысл, что в общем случае оптимизатор запросов просто игнорирует это.
6
Вы можете сравнить план казней с и без1=1
Люк М
4
@ Люк М: Я сделал это для SQLite. Оказывается, это не оптимизирует WHILE 1=1пункт. Тем не менее, это не оказывает заметного влияния на время выполнения.
Ден04

Ответы:

23

Все основные РСУБД, насколько я знаю, имеют постоянные оценки. Это должно оцениваться практически мгновенно в любом из них.

JNK
источник
+1 Это тоже мое предположение, но причина, по которой я задал вопрос, заключалась в том, чтобы получить немного больше деталей. Я собираюсь держать это открытым немного дольше, чтобы увидеть, получу ли я больше информации.
транзистор1
2
Это игнорируется. Это ничего не значит с оптимизатором, просто констатирую, где условия согласно указанной ссылке (мой ответ тоже)
gbn
8

С точки зрения SQL Server, если вы делаете это WHERE 1=1для обеспечения динамической передачи параметров и пропуска параметра из оценки, я бы посоветовал вам прочитать пару статей из SQL Server MV Erland Sommarskog. Его подход избавляет от необходимости делать некоторые другие трюки внутри динамического SQL (например, WHERE Column = Columnконструкцию или использование WHERE (Col = Val OR 1=1) and (Col2 = Val2 OR 1=1)конструкции). «1 = 1» не должно вызывать проблем с производительностью, как упомянул @JNK (я добавил +1 к его ответу, и это тот, который следует принять), я думаю, вы найдете несколько хороших советов из статьи Эрланда о Динамический SQL, и вы также увидите, что он все еще использует тот 1=1для случаев, когда параметры не передаются, но он избегает их для отдельных параметров, которые не передаются, он просто не '

Майк Уолш
источник
Я просто просматриваю вторую статью (потому что я не пишу код 2008 SP1 на данный момент), но я вижу , что он будет с помощью 1 = 1 в его коде. Я уже знаком с sp_executesql, но это не устраняет необходимость использовать 1 = 1 само по себе. Может я что-то упустил?
транзистор1
2
+1 - Erland - это ресурс, посвященный подобным вещам.
JNK
Просто цитирую вторую ссылку: «В строках 19-29 я сочиняю базовую строку SQL. Условие WHERE 1 = 1 в строке 29 позволяет пользователям вызывать процедуру без указания каких-либо параметров».
транзистор1
2
Сожалею. Я неправильно набрал свою точку зрения. Буду редактировать. Я не хотел подразумевать, что есть проблема с конструкцией Where 1 = 1, просто предлагая другие советы по удобочитаемости и, надеюсь, избегая использования подхода WHERE (column = value или 1 = 1) и (column1 = value1 или 1 = 1) и т. Д. Подход.
Майк Уолш
6

С MySQL вы можете проверить, запустив EXPLAIN EXTENDED и позже SHOW WARNINGS, чтобы увидеть фактический запрос. TL; DR: это оптимизируется.

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
Отличный ответ. Btw MySQL server v5.7.18 говорит, что «EXTENDED» устарел и будет удален в следующем выпуске. Из 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.он был удален в MySQL v 8.0.
mikep