У меня есть SP с параметром, который имеет значение NULL в качестве значения по умолчанию, а затем я хочу сделать запрос следующим образом:
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND (a.VersionId = @VersionId OR (@VersionId IS NULL AND a.VersionId IS NULL));
В WHERE
вышеуказанные проверки для обоих значение , отличное от NULL , и значение NULL для @VersionId
.
Было бы лучше с точки зрения производительности вместо этого использовать IF
оператор и дублировать запрос в один, который ищет не NULL, а другой для NULL, вот так? :
IF @VersionId IS NULL BEGIN
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND a.VersionId IS NULL;
ELSE BEGIN
SELECT ...
FROM ...
WHERE a.Blah = @Blah AND a.VersionId = @VersionId;
END
Или оптимизатор запросов делает то же самое?
ОБНОВИТЬ:
(Примечание: я использую SQL Server)
(И насколько я знаю, использование a.VersionId = @VersionId
в обоих случаях не сработает, не так ли?)
sql-server-2008
performance
user2173353
источник
источник
Ответы:
Этот шаблон
можно заменить на
Это позволит вам сопоставить NULL с NULL и позволит движку эффективно использовать индекс
column
. Для превосходного углубленного анализа этой техники я отсылаю вас к статье блога Пола Уайта:Поскольку в вашем конкретном случае есть два аргумента, вы можете использовать одну и ту же технику сопоставления
@Blah
- таким образом вы сможете переписать все предложение WHERE более или менее лаконично:Это будет работать быстро при включенном индексе
(a.Blah, a.VersionId)
.В этом случае да. Во всех версиях (по крайней мере) начиная с SQL Server 2005 и далее оптимизатор может распознать шаблон
col = @var OR (@var IS NULL AND col IS NULL)
и заменить его соответствующимIS
сравнением. Это зависит от внутреннего соответствия перезаписи, поэтому могут быть более сложные случаи, когда это не всегда надежно.В версиях SQL Server от 2008 SP1 CU5 включительно вы также можете использовать Оптимизацию встраивания параметров через
OPTION (RECOMPILE)
, где значение времени выполнения любого параметра или переменной встраивается в запрос как литерал перед компиляцией.Так что, по крайней мере, в значительной степени, в этом случае выбор зависит от стиля, хотя
INTERSECT
конструкция, несомненно, компактна и элегантна.В следующих примерах показан «один и тот же» план выполнения для каждого варианта (исключая литералы и ссылки на переменные):
источник