Você pode forçar o SQL Server a usar um índice na coluna computada para uma operação comutativa?
Infelizmente temos uma tabela no SQL Server da seguinte forma
CREATE TABLE [dbo].[Data](
[ID] [int] NOT NULL,
[ValDate] [datetime] NOT NULL,
[ValHour] [int] NOT NULL,
[ValMin] [int] NOT NULL,
[Value] [float] NULL,
[Flag_ID] [int] NOT NULL,
CONSTRAINT [PK_Data] PRIMARY KEY CLUSTERED
([ID],[ValDate],[ValHour],[ValMin]) ON [PRIMARY]
) ON [PRIMARY]
Mesmo que ValDate seja um DATETIME, ele armazena apenas a parte da data.
Alguns aplicativos antigos usando esse banco de dados fazem a seguinte consulta
SELECT ID, ValDate, ValHour, ValMin, Value
FROM DATA
WHERE ID = @id
AND @start < DATEADD(minute, ValMin, DATEADD(hour, ValHour, ValDate))
AND DATEADD(minute, ValMin, DATEADD(hour, ValHour, ValDate)) <= @end
Isso fica mais lento com muitos dados, pois o SQL não pode usar as datas especificadas na cláusula WHERE para buscar e deve varrer cada entrada da tabela com ID = @id para encontrar todas as linhas.
Não podemos alterar os aplicativos, então decidi adicionar uma coluna computada e colocar um INDEX nela
ALTER TABLE dbo.Data ADD ComputedDateTime AS
DATEADD(minute, ValMin, DATEADD(hour, ValHour, ValDate))
GO
CREATE NONCLUSTERED INDEX [Data_ComputedDateTime_IDX] ON [dbo].[Data]
([ComputedDateTime], [ID])
INCLUDE ([ValDate], [ValHour], [ValMin], [Value])
Isso torna a consulta original rápida, mas se eu mudar a ordem dos DATEADD's, adicionando o minuto à data e depois a hora o índice não é utilizado.
Então, suponho que isso seja porque o SQL Server não percebe que as operações são comutativas, ou seja (data + hora) + minuto = (data + minuto) + hora
Existe alguma maneira de acelerar os dois pedidos de computação, sem criar duas colunas computadas e dois índices?
Até onde sei, suas únicas opções são criar a segunda coluna computada, entrar em contato com o fornecedor do software para solicitar uma correção ou enviar uma solicitação de aprimoramento à Microsoft para obter melhor suporte para seu cenário. Na superfície, a funcionalidade que você está solicitando pode ser vista como simples: por que o SQL Server não consegue descobrir que as expressões são equivalentes quando obviamente são para um programador? No entanto, requer pelo menos todos os seguintes:
O SQL Server precisa saber que
DATEADD(minute, ValMin, DATEADD(hour, ValHour, ValDate))
é igual aDATEADD(hour, ValHour, DATEADD(minute, ValMin, ValDate))
. Existem muitas equivalências de datas que o SQL Server ainda não conhece, e esta é uma delas.O otimizador de consulta precisaria procurar correspondências comutativas durante a correspondência de colunas computadas .
O otimizador de consulta precisaria encontrar sua correspondência durante o processo de otimização de consulta, que foi projetado para fornecer rapidamente um plano "bom o suficiente".
Sou solidário ao seu problema, mas meu palpite é que o cenário que você está descrevendo não é comum o suficiente para a Microsoft fazer melhorias nessa área, especialmente quando há uma solução simples que pode ser realizada alterando o código ou adicionando outra coluna computada à tabela.