T-SQL 1 = 1 Производительность
Для моих 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
...
Ответы
Ответ 1
Скорее всего, если вы используете профайлер и посмотрите, вы в конечном итоге увидите, что оптимизатор в конечном итоге игнорирует это чаще, чем нет, поэтому в великой схеме вещей, вероятно, не будет много способ повышения производительности или потерь.
Ответ 2
Нет, SQL Server достаточно умен, чтобы исключить это условие из плана выполнения, поскольку он всегда TRUE
.
То же самое верно для Oracle, MySQL и PostgreSQL.
Ответ 3
Это не влияет на производительность, но там текст SQL выглядит так, будто он искажен атакой SQL-инъекции. Трюк "1 = 1" появляется во многих атаках на основе инъекций на основе sql. Вы просто рискуете, что какой-то ваш клиент когда-нибудь развернет "черный ящик", который контролирует трафик SQL, и вы обнаружите, что ваше приложение помечено как "взломанный". Это могут указывать и анализаторы исходного кода. Конечно, это длинный выстрел, но что-то стоит положить в равновесие.
Ответ 4
Нет никакой разницы, поскольку они оценивали константы и оптимизировались. Я использую как 1 = 1, так и 0 = 1 как в списках AND
, так и в коде OR
сгенерированных кодом и кодом, и он не имеет эффекта.
Ответ 5
Так как условие всегда верно, SQL Server игнорирует его. Вы можете проверить, выполнив два запроса, один с условием и один без, и сравнив два фактических плана выполнения.
Альтернативой вашей легкости комментирования является реструктуризация вашего запроса:
SELECT ...
FROM table t
WHERE
t.[column1] = @param1 AND
t.[column2] = @param2 AND
t.[column3] = @param3
Затем вы можете добавлять/удалять/прокомментировать строки в тех условиях, где он будет, и он будет по-прежнему действительным SQL.
Ответ 6
Не удавалось достичь производительности. Даже если ваше предложение WHERE загружено большим количеством сравнений, это крошечно.
Лучший сценарий - это сравнение бит-бит. Хуже того, цифры считаются целыми числами.
Ответ 7
Для запросов любой разумной сложности разница не будет. Вы можете посмотреть некоторые планы выполнения, а также сравнить реальные затраты на выполнение и убедиться сами.
Ответ 8
Одним из потенциально незначительно негативных последствий этого является то, что AND 1=1
остановит запуск SQL Server простой параметризации.
Демо script
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
скомпилировали и сохранили отдельный план для разных постоянных значений.
![введите описание изображения здесь]()
В идеале вы не должны полагаться на это в любом случае и должны явно указывать параметры для обеспечения параметризации требуемых элементов, а параметры имеют правильные типы данных.