Как сделать быстрее это утверждение: «paramDate между startDate и NULL»? - PullRequest
2 голосов
/ 11 мая 2009

Этот запрос занимает много времени, когда endDate имеет значение NULL (я думаю, что это о выражении 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) 

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

Ответы [ 4 ]

1 голос
/ 11 мая 2009

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

То, как вы написали это, вы запрашиваете, чтобы GETDATE () оценивался каждый раз, когда enddate равен нулю.

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

1 голос
/ 11 мая 2009

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

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

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

SELECT * 
  FROM HastaKurumlari
WHERE @when
BETWEEN startDate AND endDate

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

1 голос
/ 11 мая 2009

Вот запрос без CONVERT или CASE:

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)
1 голос
/ 11 мая 2009

Вы можете попробовать функцию coalesce :

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

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

...