2009-09-18 2 views
6

У меня есть этот пункт на объединение в хранимой процедуре я унаследовал:T-SQL ISNULL) Оптимизация (

WHERE a.is_active = 1 
AND b.due_date <= ISNULL(@due_date_limit, b.due_date) 

Как бы я вновь пишу это, чтобы удалить ISNULL, как это вызывает серьезные проблемы с производительностью?

+0

SQL Server? – AnthonyWJones

ответ

7

в этом случае, я бы, если заявление, проверка @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 
2
AND @due_date_limit IS NULL OR b.due_date <= @due_date_limit 

, но я не уверен, что это будет намного быстрее.

+0

Если есть индекс, то он есть. – recursive

+0

Индекс не вызывает беспокойства - даже если он существует, индекс будет использоваться только во второй половине. Это намного лучше, чем предложения ISNULL/COALESCE. –

1

@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> 
1
COALESCE(@due_date_limit, b.due_date) 

может помочь

+0

Это будет обрабатывать вещи изящно, но это отходы для выполнения 1 = 1 эквивалента. –

2

есть ли указатель на 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 равно нулю), или фильтрация с помощью < = потенциально может возвращать значительное количество записей, которые исключит любую возможность для использования индекса и потребует полного сканирования таблицы. Это может быть то, что вы испытываете.

3

Наиболее частой причиной низкой производительности с этим типом запросов является то, что оптимизатор не может быть уверен, что типичное значение @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')) 
+0

Если параметр равен нулю, почему вы все еще хотите сравнить значения? Вы этого не сделаете, поэтому не используйте ISNULL/COALESCE для дополнительных параметров. –

0

С @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 
+0

Ответ ответчика - лучшее решение, если вам нужно, чтобы он был таким же, как и запись столбца, чтобы соответствовать условию '<=' оператора, в противном случае установить, если перед запросом, как это, так как он будет быстрее и нет проверки. – johntrepreneur

Смежные вопросы