Como tornar mais rápida a seguinte declaração: “paramDate Entre startDate e NULL”?
-
21-08-2019 - |
Pergunta
Esta consulta está tomando muito tempo quando endDate é nulo (eu acho que a sua declaração de caso sobre, antes de declaração caso era rápido)
SELECT *
FROM HastaKurumlari
WHERE CONVERT(SMALLDATETIME,'21-05-2009',103)
BETWEEN startDate
AND (CASE WHEN endDate IS NULL THEN GETDATE() ELSE endDate END)
O que devo usar, quando endDate é nulo para torná-lo mais rápido?
Solução
Aqui está a consulta sem converter ou CASE:
SELECT *
FROM HastaKurumlari
WHERE '21-05-2009' between startDate and IsNull(endDate,getdate())
Para se certificar doens't Sql Server avaliar getdate () para cada linha, você pode armazená-lo, embora eu tenho certeza que o SQL Server é bastante inteligente por padrão:
declare @now datetime
set @now = getdate()
SELECT *
FROM HastaKurumlari
WHERE '21-05-2009' between startDate and IsNull(endDate,@now)
Publicação do plano de consulta pode ajudar a explicar por que a consulta é lento:
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)
Outras dicas
Se é desempenho crítico, então talvez só não use null
para a data final aberto -. Usar o máximo suportado de data e hora em vez (provavelmente lotes de 9s)
Eu também fazer a conversão separadamente:
DECLARE @when datetime
SET @when = CONVERT(SMALLDATETIME,'21-05-2009',103)
SELECT *
FROM HastaKurumlari
WHERE @when
BETWEEN startDate AND endDate
Ainda há algo um pouco diferente do acima e seu original; se você pode explicar o intenção do cheque GETDATE()
eu poderia ser capaz de arrumado (leia-se: correção) um pouco
Como ponto de partida, fator fora GETDATE () para que o seu chamado apenas uma vez, e você deve ver uma melhoria na velocidade.
A maneira que você escreveu que você está pedindo para GETDATE () para ser avaliado cada vez enddate é nulo.
Desde GETDATE () é uma não-determinístico Função a consulta não pode ser otimizado e tenderá a sob executar.
Você poderia tentar o href="http://doc.ddart.net/mssql/sql70/ca-co_8.htm" rel="nofollow noreferrer"> coalesce função :
select *
from HastaKurumlari
where convert(smalldatetime, '21-05-2009', 103)
between startDate and coalesce(endDate, getdate());
A única maneira de ter certeza é tentar todas as alternativas e ver o plano de execução gerado para cada consulta.