Eu tenho uma consulta que usa uma função no predicado, algo como isto:
commentType = 'EL'
AND commentDateTime >= DATEADD(month,datediff(month,0,getdate()) - 13,0)
Eu tenho um índice filtrado no commentType que tem 40K linhas e, quando executo a consulta, o número estimado de linhas para a Busca por Índice é muito preciso (em torno de 11K), mas para a próxima etapa (operador de classificação) ele ignora completamente as estatísticas e apenas estima o número total de linhas no índice filtrado.
Por que isso está acontecendo? Eu sei o básico sobre sargabilidade e testei apenas por uma questão de sanidade, substituindo os dados datados por uma data real (01-01-2014) e pronto ... O tipo começou a adivinhar o número de linhas corretamente ...
Por que isso está acontecendo e como posso corrigi-lo? Não posso passar uma data fixa ...
sql-server
index
statistics
MrKudz
fonte
fonte
DATEADD(month,datediff(month,0,getdate()) - 13,0)
não faz sentido para mim. O que você está tentando fazer com isso? Pode ser melhorado / simplificado?DATEADD(month, -13, DATEADD(day, 1-DATEPART(day, SYSDATETIME()))
ver se há alguma diferença?(commentType, commentDate)
, ele se comporta melhor lá? Às vezes, os índices filtrados podem às vezes relatar estimativas em pontos diferentes dos planos. A estimativa parece muito clara ao informar o número total no índice filtrado, mas na verdade o plano está sendo mostrado incorretamente.Respostas:
Acredito que suas estimativas estão erradas por causa de um bug no estimador que troca dois dos argumentos DATEDIFF. Eu falo sobre isso aqui:
Uma solução alternativa é calcular o primeiro dia de 13 meses atrás sem usar DATEDIFF (2008 ou posterior):
Não tenho certeza de que abordará a estimativa (não testei com índices filtrados e não sei o que a classificação está realmente fazendo ou por que ela tem uma estimativa diferente sem o plano e / ou o restante da consulta )
A correção que a Microsoft recomenda é usar o TF 4199, mas não tenho certeza de que você precisará fazer aqui:
Outra opção seria garantir que você esteja no SP / CU mais recente absoluto para qualquer versão do SQL Server que estiver usando, pois eles alegam que o problema foi corrigido no seguinte artigo da KB (embora isso ainda exija o uso do TF 4199 a menos que você esteja em 2014 ou melhor):
A correção pode ser obtida com as seguintes compilações:
(Da próxima vez, inclua os resultados de
SELECT @@VERSION
em sua pergunta.)Observarei que o artigo da KB diz que DATEDIFF pode subestimar o número de linhas, que é o oposto do que está acontecendo no seu cenário. Isso não significa que as correções não se aplicam a você; Acho que a redação do artigo da KB é imprecisa, pois as estimativas podem variar de acordo com os dados e o intervalo que você está olhando.
Meu post acima confirmou que a troca não ocorre mais em 2014 e acima. Para estar seguro, provavelmente retiraria DATEDIFF do seu predicado e usaria um método diferente para calcular o início do seu intervalo. Não sugiro o exagero de 4199 ou o uso de SQL dinâmico para impedir a troca incorreta.
fonte