Подтвердить что ты не робот

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 всегда начинается с благих намерений (по крайней мере, в этих частях).

4b9b3361

Ответ 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?