Tenho a seguinte consulta no SQL server:
declare @timestamp_start date = getdate() - 1
declare @timestamp_end date = getdate()
SELECT
my_date = a.itemTimestamp
FROM
my_table a with(nolock)
WHERE
(@timestamp_start is null OR a.itemTimestamp >= @timestamp_start)
AND (@timestamp_end is null OR a.itemTimestamp < @timestamp_end)
É extremamente lento (90s para < 2000 registros), porque o plano de execução usa o índice clusterizado da coluna PK para 'my_table':
Por que isso está acontecendo e como posso otimizar o desempenho da consulta?
Qual é o tipo de dados de itemTimestamp? Essa coluna é indexada? A coluna é anulável?
Supondo que as respostas sejam
datetime
, Sim e Não, respectivamente, você pode considerarSe você alterar
datetime2
e realmente armazenar datas anteriores a 1753, precisará alterar a condição de limite inferior para00010101
. Isso também não trará de volta as datas correspondentes ao limite superior de9999-12-31
- mas no mundo real é improvável que isso cause um problema.É
my_table.itemTimestamp
umDATE
tipo de dados real ouDATETIME
? Parece um nome de coluna estranho para um tipo de dados que não possui componente de tempo ;-). Se for umDATETIME
, a etapa 1 é usar o tipo de dados apropriado para a variável. Mas, se for realmente umaDATE
coluna, tente a seguinte consulta. Ele divide as 4 permutações para que o SQL Server possa ter consultas simples e concisas em vez de uma consulta do tipo tudo com um monte deOR
s que muitas vezes complicam os planos de consulta.Apenas para bancar o advogado do diabo (em alguns círculos isso é desaprovado), se você tem CERTEZA de que deseja usar esse índice e melhorar as coisas, adicione uma dica de índice ... índices ou consultas no futuro. Adicionar: COM (ÍNDICE (###SEU NOME DO ÍNDICE AQUI##))