В контексте процедурной партии IF / ELSE
Это не имеет никакого значения. Буквально требуется 0,00 мс, чтобы определить, является ли значение пустым или неизвестным, требуется 0,00 мс, чтобы определить, ISNULL(@SKU, '') = ''
. Если есть разница, она, скорее всего, будет измеряться в наносекундах ИМО. Опять же, это в контексте процедурной партии , поскольку оператор оценивается только один раз.
В контексте ФИЛЬТРА (например, ON, WHERE или HAVING CLAUSE)
Здесь разница на самом деле огромна, ее невозможно преуменьшить. Это сложно объяснить с помощью параметров и переменных, поэтому для краткости я покажу вам пример с этими примерами данных:
IF OBJECT_ID('tempdb..#things','U') IS NOT NULL DROP TABLE #things;
SELECT TOP (10000) Txt = SUBSTRING(LEFT(NEWID(),36),1,ABS(CHECKSUM(NEWID())%x.N))
INTO #things
FROM (VALUES(1),(30),(40),(NULL)) AS x(N)
CROSS JOIN sys. all_columns;
UPDATE #things SET Txt = NEWID() WHERE txt = '0';
CREATE NONCLUSTERED INDEX nc_things1 ON #things(Txt);
Следующие запросы найдут строки, которые содержат или не содержат пробелы или nulls
-- Finding things that are blank or NULL
SELECT t.Txt
FROM #things AS t
WHERE t.Txt IS NULL OR t.Txt = '';
-- Finding things that are NOT blank or NULL
SELECT t.Txt
FROM #things AS t
WHERE NOT(t.Txt IS NULL OR t.Txt = '');
SELECT t.Txt
FROM #things AS t
WHERE t.Txt > '';
-- Finding things that are blank or NULL
SELECT t.Txt
FROM #things AS t
WHERE ISNULL(t.Txt,'') = '';
-- Finding things that are NOT blank or NULL
SELECT t.Txt
FROM #things AS t
WHERE ISNULL(t.Txt,'') <> '';
Первые три запроса SARGable, последние два не из-за ISNULL. Хотя есть индекс, чтобы помочь мне, ISNULL делает его здесь бесполезным. Разница заключается в том, чтобы попросить кого-нибудь поискать в телефонной книге всех, чье имя начинается с с «А», и найти всех, чье имя заканчивается на «А».
Предикаты SARGable позволяют запросу искать часть индекса, где предикаты, отличные от SARGable, заставляют запрос сканировать всю таблицу REGARDLESS, сколько совпадающих строк существует (если есть). Когда вы имеете дело с миллионами / миллиардами строк, соединенных со многими другими таблицами, разница может заключаться в том, что запрос выполняется в считанные секунды, а в некоторых случаях он может выполняться часами или даже неделями (я видел несколько).
ПЛАНЫ ИСПОЛНЕНИЯ:
![enter image description here](https://i.stack.imgur.com/RwPQF.png)
Обратите внимание, что этот последний WHERE t.Txt > ''
также будет работать. Любое ненулевое текстовое значение равно > ''
, и если t.Txt было НЕДЕЙСТВИТЕЛЬНО, оно также оценивается как ложное. Я включил это, потому что это выражение работает для отфильтрованных индексов. Единственная загвоздка в том, что вы не можете использовать его в текстовом поле, где неявное преобразование может преобразовать это в число 0 или меньше. Обратите внимание на следующие запросы:
IF '' = 0 PRINT 'True' ELSE PRINT 'False'; -- Returns True
IF '' = '0' PRINT 'True' ELSE PRINT 'False'; -- Returns False
IF '' > -1 PRINT 'True' ELSE PRINT 'False'; -- Returns True
IF '' > '-1' PRINT 'True' ELSE PRINT 'False'; -- Returns False