T-SQL 1 = 1 Хит производительности - PullRequest
17 голосов
/ 26 июня 2009

Для моих запросов SQL я обычно делаю следующее для операторов SELECT:

SELECT ...
FROM table t
WHERE 1=1
  AND t.[column1] = @param1
  AND t.[column2] = @param2

Это облегчит задачу, если мне нужно будет добавить / удалить / прокомментировать любые предложения WHERE, поскольку мне не нужно заботиться о первой строке.

Есть ли какое-либо снижение производительности при использовании этого шаблона?

Дополнительная информация:

Пример для sheepsimulator и всех других, кто не получил использование.

Предположим, что вышеупомянутый запрос, мне нужно изменить @ param1, чтобы не включать в запрос:

С 1 = 1:

...
WHERE 1=1 <-- no change
  --AND t.[column1] = @param1 <-- changed
  AND t.[column2] = @param2 <-- no change
...

Без 1 = 1:

...
WHERE <-- no change
  --t.[column1] = @param1 <-- changed
  {AND removed} t.[column2] = @param2 <-- changed
...

Ответы [ 8 ]

17 голосов
/ 26 июня 2009

Нет, SQL Server достаточно умен, чтобы пропустить это условие в плане выполнения, поскольку он всегда TRUE.

То же самое верно для Oracle, MySQL и PostgreSQL.

11 голосов
/ 26 июня 2009

Вполне вероятно, что если вы используете профилировщик и посмотрите, вы в конечном итоге увидите, что оптимизатор будет игнорировать это чаще, чем нет, так что в общей схеме, вероятно, не будет много в способ увеличения производительности или потерь.

3 голосов
/ 26 июня 2009

Это не влияет на производительность, но там текст SQL выглядит так, как будто он был искажен атакой SQL-инъекции.Уловка «1 = 1» появляется во многих атаках на основе инъекций SQL.Вы просто рискуете, что когда-нибудь ваш клиент развернет «черный ящик», который отслеживает трафик SQL, и вы обнаружите, что ваше приложение помечено как «взломанное».Также анализаторы исходного кода могут пометить это.Конечно, это длинный, длинный выстрел, но кое-что стоит поставить на баланс.

2 голосов
/ 26 июня 2009

Поскольку условие всегда выполняется, SQL Server будет игнорировать его. Вы можете проверить, выполнив два запроса, один с условием, а другой без, и сравнив два фактических плана выполнения.

Альтернативой для достижения вашего удобства комментирования является реструктуризация вашего запроса: SELECT ... FROM table t WHERE t.[column1] = @param1 AND t.[column2] = @param2 AND t.[column3] = @param3

Затем вы можете добавить / удалить / закомментировать строки в условиях where, и это все равно будет действительным SQL.

2 голосов
/ 26 июня 2009

Разницы нет, так как они оценивают константы и оптимизируются. Я использую как 1 = 1, так и 0 = 1 в списках AND и OR, сгенерированных как вручную, так и в коде, и это не имеет никакого эффекта.

1 голос
/ 25 мая 2015

Одним из потенциально умеренно негативных последствий этого является то, что AND 1=1 остановит запуск средства простой параметризации SQL Server.

Демонстрационный скрипт

DBCC FREEPROCCACHE;  /*<-- Don't run on production box!*/

CREATE TABLE [E7ED0174-9820-4B29-BCDF-C999CA319131]
(
X INT, 
Y INT,
PRIMARY KEY (X,Y)
);

GO
SELECT *
FROM   [E7ED0174-9820-4B29-BCDF-C999CA319131]
WHERE  X = 1
       AND Y = 2;
GO
SELECT *
FROM   [E7ED0174-9820-4B29-BCDF-C999CA319131]
WHERE  X = 2
       AND Y = 3;
GO   
SELECT *
FROM   [E7ED0174-9820-4B29-BCDF-C999CA319131]
WHERE  1 = 1
       AND X = 1
       AND Y = 2 
GO   
SELECT *
FROM   [E7ED0174-9820-4B29-BCDF-C999CA319131]
WHERE  1 = 1
       AND X = 2
       AND Y = 3    

SELECT usecounts,
       execution_count,
       size_in_bytes,
       cacheobjtype,
       objtype,
       text,
       creation_time,
       last_execution_time,
       execution_count
FROM   sys.dm_exec_cached_plans a
       INNER JOIN sys.dm_exec_query_stats b
         ON a.plan_handle = b.plan_handle
       CROSS apply sys.dm_exec_sql_text(b.sql_handle) AS sql_text
WHERE  text LIKE '%\[E7ED0174-9820-4B29-BCDF-C999CA319131\]%' ESCAPE '\'
       AND text NOT LIKE '%this_query%'
ORDER BY last_execution_time DESC       

GO

DROP TABLE [E7ED0174-9820-4B29-BCDF-C999CA319131]   

Показывает, что оба запроса без 1=1 были удовлетворены одной параметризованной версией кэшированного плана, тогда как запросы с 1=1 скомпилировали и сохранили отдельный план для различных постоянных значений.

enter image description here

В идеале, вы все равно не должны полагаться на это и должны явно задавать параметры запросов, чтобы гарантировать, что желаемые элементы параметризованы и параметры имеют правильные типы данных.

1 голос
/ 26 июня 2009

Для запросов любой разумной сложности не будет никакой разницы. Вы можете посмотреть на некоторые планы выполнения, а также сравнить реальные затраты на выполнение и убедиться сами.

1 голос
/ 26 июня 2009

Нет производительности. Даже если ваше предложение WHERE загружено большим количеством сравнений, оно крошечно.

В лучшем случае это сравнение по битам. В худшем случае цифры оцениваются как целые числа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...