T-SQL Isnull() оптимизация
У меня есть это предложение о соединении в хранимой процедуре, которую я унаследовал:
WHERE a.is_active = 1
AND b.due_date <= ISNULL(@due_date_limit, b.due_date)
Как бы я переписал это, чтобы удалить ISNULL, поскольку это вызывает серьезные проблемы с производительностью?
7 ответов
в этом случае у меня будет оператор if, проверяющий @due_date_limit
IF (@due_date_limit IS NULL)
BEGIN
...
WHERE a.is_active = 1 --not required to compare b.due_date <= b.due_date
END
ELSE
BEGIN
...
WHERE a.is_active = 1
AND b.due_date <= @due_date_limit
END
наиболее распространенной причиной низкой производительности с этим типом запроса является то, что оптимизатор не может быть уверен, какое обычно значение @due_date_limit будет для большинства запросов. Часто план, созданный и повторно используемый последующими исполнениями, благоприятствует случаю, когда значение равно null.
начиная с SQL 2005 вы можете направлять оптимизатор, используя опцию" оптимизировать для": -
WHERE a.is_active = 1
AND b.due_date <= ISNULL(@due_date_limit, b.due_date)
OPTION (OPTIMIZE FOR (@due_date_limit = '09/01/2009'))
AND @due_date_limit IS NULL OR b.due_date <= @due_date_limit
но я не уверен, что это будет гораздо быстрее.
есть ли индекс на due_Date? Если не добавить один, а затем проверить производительность. Если уже есть, то измените на два отдельных оператора
If @due_date_limit is null
Select [stuff]
From Table
Else
Select [stuff]
From Table
Where b.due_date <= @due_date_limit
но поймите, что не фильтрация (когда @due_date_limit равно null) или фильтрация с помощью
@due_date_limit-это переменная хранимой процедуры, поэтому она может быть учтена из этого запроса вместе:
if (@due_date_limit is NULL)
<run query that works when @due_date_limit is NULL>
else
<run query that works when @due_date_limit is NOT NULL>
С @due_date_limit
является переменной хранимой процедуры, вы можете просто проверить его на NULL
перед запросом и установите его в значение по умолчанию, если это необходимо, таким образом, устраняя проверку ISNULL в WHERE
предложения.
IF (@due_date_limit IS NULL)
BEGIN
SET @due_date_limit = '09/01/2009';
END
и тогда ваш WHERE
предложение будет просто выглядеть так:
WHERE a.is_active = 1
AND b.due_date <= @due_date_limit