Sql-выражения с равными vs в
Скажите, что кто-то подошел к вам и сказал, что мы сократим количество SQL, которое мы пишем, заменив equals на IN
. Использование было бы как для одиночных скалярных значений, так и для списков чисел.
SELECT *
FROM table
WHERE id = 1
ИЛИ
SELECT *
FROM table
WHERE id IN (1)
Являются ли эти утверждения эквивалентными тому, что создает оптимизатор?
Это выглядит очень просто на поверхности, но это приводит к упрощению по двум причинам: 1. большие блоки SQL не нужно дублировать, а 2. мы не злоупотребляем динамическим SQL.
Это надуманный пример, но рассмотрим следующее.
select a.* from tablea a
join tableb b on a.id = b.id
join tablec c on b.id2 = c.id2
left join tabled d on c.id3 = c.id3
where d.type = 1
... и то же самое снова для более чем одного случая
select a.* from tablea a
join tableb b on a.id = b.id
join tablec c on b.id2 = c.id2
left join tabled d on c.id3 = c.id3
where d.type in (1,2,3,4)
(это даже не большой оператор)
предположительно вы могли бы выполнять конкатенацию строк, но это нежелательно в свете использования ORM, а динамическая конкатенация строк SQL всегда начинается с благих намерений (по крайней мере, в этих частях).
Ответы
Ответ 1
В обоих случаях будет выполнен один и тот же план выполнения: либо table scan
, index scan
, либо index seek
, в зависимости от того, как индексировать вашу таблицу.
Вы можете сами убедиться - Отображение графических планов выполнения (SQL Server Management Studio) - См. раздел "Использование параметров плана выполнения".
Ответ 2
Эти два конкретных утверждения эквивалентны оптимизатору (сравнили ли вы планы выполнения?), но я думаю, что более важная выгода от этого заключается в том, что
WHERE id = 1 OR id = 2 OR id = 3 OR id = 4 OR id = 5
Может быть выражено следующим, гораздо более сжатым и читаемым (но семантически эквивалентным оптимизатору) версией:
WHERE id IN (1,2,3,4,5)
Проблема в том, что, когда они выражаются последним, большинство людей думает, что они могут передать строку, например @list = '1,2,3,4,5'
, а затем сказать:
WHERE id IN (@list)
Это не работает, потому что @list
- это единственная скалярная строка, а не массив целых чисел.
В случаях, когда у вас есть одно значение, я не вижу, как эта "оптимизация" помогает чему-либо. Вы не указали меньше SQL, вы на самом деле писали больше. Можете ли вы более подробно описать, как это приведет к меньшему количеству SQL?