Як правило, "WHERE 1 = 1" впливає на ефективність запитів?


19

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

Взагалі кажучи, чи впливає це доповнення до статусу SQL негативно на ефективність запитів? Я не шукаю відповіді щодо конкретної системи баз даних (тому що я використовував її в DB2, SQL Server, MS-Access і mysql) - якщо тільки неможливо відповісти, не вдаючись до конкретних даних.


4
Я вірю, що будь-який оптимізатор міг би впоратися з такою простою умовою і просто проігнорувати його, щоб остаточний план виконання не містив би його взагалі

Я б так думав - логічно кажучи, мабуть, є сенс, що оптимізатор запитів, як правило, просто ігнорує його.

6
Ви можете порівняти план розстрілів з без та1=1
Люк М

4
@Luc M: Я зробив саме це для SQLite. Виявляється, це не оптимізує WHILE 1=1застереження. Однак, схоже, це не має жодного помітного впливу на час виконання.
dan04

Відповіді:


23

Всі основні RDBMS, наскільки я знаю, вбудовані в постійні оцінки. Це мало б оцінити миттєво в будь-якому з них.


+1 Також це було моїм здогадом, але я поставив питання, щоб детальніше ознайомитись. Я буду тримати його відкритим трохи довше, щоб побачити, чи отримаю я більше інформації.
транзистор1

2
Це ігнорується. З оптимізатором це нічого не стосується, лише контингент, де відбувається умова відповідно до посилань (моя відповідь теж)
gbn

8

З точки зору сервера SQL, якщо ви робите це, WHERE 1=1щоб дозволити динамічне проходження параметрів і пропуск параметра з оцінювання, я б запропонував вам прочитати кілька статей з SQL Server MV Ерланда Соммарського. Його підхід усуває необхідність робити деякі інші хитрощі в динамічному 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 - Ерланд - це основний ресурс для подібних речей.
JNK

Просто цитую з другого посилання: "У рядках 19-29 я складаю основний рядок SQL. Умова, де 1 = 1 у рядку 29, є для того, щоб дозволити користувачам викликати процедуру, не вказуючи взагалі жодних параметрів."
транзистор1

2
Вибачте. Я неправильно ввів свою думку. Відредагуємо. Я не мав на увазі, що існує проблема з конструкцією Where 1 = 1, просто пропонуючи інші поради щодо читабельності і, сподіваюся, уникати підходу WHERE (стовпець = значення або 1 = 1) і (column1 = value1 або 1 = 1) тощо. Підхід.
Майк Уолш

6

За допомогою MySQL ви можете перевірити, запустивши EXPLAIN EXTENDED та пізніше ПОКАЗУВАТИ ПОПЕРЕДЖЕННЯ, щоб побачити фактичний запит. 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 v5.7.18 говорить, що "EXTENDED" є застарілим і буде видалено в майбутньому випуску. З 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.її видалено в MySQL v 8.0.
мікеп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.