Tenho a seguinte consulta:
SELECT u.userId,
app.applicationId
FROM app.application AS app
INNER JOIN app.applicant AS ap
ON ap.applicantId = app.applicantId
INNER JOIN usr.[user] AS u
ON u.userId = ap.userId
LEFT JOIN msg.emailTemplateSent AS t
ON t.toUserId = u.userId
AND t.emailTemplateName = 'v4_before_sixWeek_latestFlight_reminder'
WHERE Convert(Date, GETUTCDATE()) =
DATEADD(week,-6,Convert(Date, app.flightDateLatest ))
AND t.emailEventId IS NULL
ORDER BY app.applicationId ASC
Por favor, preste atenção na primeira linha da cláusula where novamente:
Convert(Date, GETUTCDATE()) = DATEADD(week,-6,Convert(Date, app.flightDateLatest ))
Eu poderia mudar isso de uma maneira que meu índice possa ser usado? O índice realmente é usado, mas é uma verificação completa.
Também pode ser visto aqui:
Esta é a minha definição de índice:
USE [APCore];
CREATE NONCLUSTERED INDEX i_flightDateLatest
ON [app].[application] ( flightDateLatest ASC )
INCLUDE ( [applicantId] , [applicationId] , [programID])
WITH ( PAD_INDEX = OFF,
FILLFACTOR = 100 ,
SORT_IN_TEMPDB = OFF ,
ONLINE = OFF,
--DROP_EXISTING = ON,
IGNORE_DUP_KEY = OFF,
STATISTICS_NORECOMPUTE = OFF,
DATA_COMPRESSION=PAGE,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON )
ON [NONCLUSTERED_INDEXES]
Este é o plano de execução completo .
Infelizmente não consigo alterar a coluna chamada flightDateLatest
de datetime para date para evitar a conversão
Além de criar uma coluna computada ou alterar o esquema, há algo mais que possa ser feito para evitar a leitura da verificação completa de tabela\índice nessa situação?
Atualizar:
Após a resposta aceita, alterou a consulta de acordo e agora o índice é usado em uma operação de busca como você pode ver na imagem abaixo.
Observe o custo de 94% da consulta original para a consulta aprimorada de 6%:
Você pode adicionar 6 semanas ao seu getutc ...
e, em seguida, testar esse dia específico (flightDateLatest) para ser maior ou igual
DATEADD(week,6,Convert(Date, GETUTCDATE()))
e menor que o dia seguinte
DATEADD(DAY,1,DATEADD(week,6,Convert(Date, GETUTCDATE())))
com saída:
calculado
Outra solução potencial é adicionar uma coluna computada à sua tabela e indexá-la, mas isso provavelmente é um exagero aqui. Faz mais sentido em situações em que sua matemática de datas é baseada em duas colunas.