Как сделать быстрее это утверждение :“Параметр Между StartDate и NULL”?

StackOverflow https://stackoverflow.com/questions/847750

  •  21-08-2019
  •  | 
  •  

Вопрос

Этот запрос занимает много времени, когда конечная дата равна нулю (я думаю, что это связано с оператором case, до оператора case это было быстро)

SELECT * 
FROM HastaKurumlari
WHERE CONVERT(SMALLDATETIME,'21-05-2009',103) 
BETWEEN startDate 
    AND (CASE WHEN endDate IS NULL THEN GETDATE() ELSE endDate END) 

Что я должен использовать, когда конечная дата равна нулю, чтобы ускорить это?

Это было полезно?

Решение

Вот запрос без ПРЕОБРАЗОВАНИЯ или РЕГИСТРА:

SELECT * 
FROM HastaKurumlari
WHERE '21-05-2009' between startDate and IsNull(endDate,getdate())

Чтобы убедиться, что Sql Server не вычисляет getdate() для каждой строки, вы могли бы кэшировать его, хотя я почти уверен, что Sql Server по умолчанию достаточно умен:

declare @now datetime
set @now = getdate()

SELECT * 
FROM HastaKurumlari
WHERE '21-05-2009' between startDate and IsNull(endDate,@now)

Публикация плана запроса может помочь объяснить, почему запрос выполняется медленно:

SET SHOWPLAN_TEXT ON
go
SELECT * 
FROM HastaKurumlari
WHERE CONVERT(SMALLDATETIME,'21-05-2009',103) 
BETWEEN startDate 
    AND (CASE WHEN endDate IS NULL THEN GETDATE() ELSE endDate END)

Другие советы

Если это критично для производительности, то, возможно, просто не используйте null для открытой конечной даты - используйте вместо этого максимально поддерживаемую дату-время (вероятно, много 9 секунд).

Я бы также сделал преобразование отдельно:

DECLARE @when datetime
SET @when = CONVERT(SMALLDATETIME,'21-05-2009',103) 

SELECT * 
  FROM HastaKurumlari
WHERE @when
BETWEEN startDate AND endDate

В приведенном выше и вашем оригинале все еще есть что-то немного отличающееся;если вы можете объяснить намерение из числа GETDATE() проверьте, что я мог бы немного привести это в порядок (читай: исправить).

В качестве отправной точки исключите функцию GETDATE(), чтобы она вызывалась только один раз, и вы должны увидеть улучшение скорости.

Судя по тому, как вы это написали, вы просите, чтобы GETDATE() вычислялась каждый раз, когда enddate имеет значение null.

Поскольку GETDATE() является недетерминированный функция, запрос не может быть оптимизирован и, как правило, недостаточно выполняется.

Вы могли бы попробовать сливаться функция:

select * 
from HastaKurumlari
where convert(smalldatetime, '21-05-2009', 103) 
    between startDate and coalesce(endDate, getdate());

Единственный способ убедиться в этом - попробовать любые альтернативы и просмотреть план выполнения, сгенерированный для каждого запроса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top