Ao diagnosticar consultas do SQL Server 2008 R2 com estimativa de cardinalidade ruim (apesar da indexação simples, estatísticas atualizadas etc. ) que contém predicados AND correlacionados no SQL Server 2008 ou no SQL Server 2008 R2 ou no SQL Server 2012
Posso adivinhar o que o artigo da KB quer dizer com "correlacionado", por exemplo, predicado nº 2 e predicado nº 1, em grande parte, visam as mesmas linhas.
Mas não sei como o SQL Server sabe dessas correlações. Uma tabela precisa de um índice de várias colunas contendo colunas de ambos os predicados? O SQL usa estatísticas para verificar se os valores de uma coluna estão correlacionados com outra? Ou algum outro método é usado?
Estou perguntando isso por dois motivos:
- para determinar quais das minhas tabelas e consultas podem ser melhoradas usando este hotfix
- para saber o que devo fazer na indexação, estatísticas, etc. para afetar #1
Considere a consulta simples do AdventureWorks e o plano de execução mostrado abaixo. A consulta contém predicados conectados com
AND
. A estimativa de cardinalidade do otimizador é de 41.211 linhas:Usando estatísticas padrão
Dadas apenas estatísticas de coluna única, o otimizador produz essa estimativa estimando a cardinalidade para cada predicado separadamente e multiplicando as seletividades resultantes juntas. Esta heurística assume que os predicados são completamente independentes.
Dividir a consulta em duas partes facilita a visualização do cálculo:
A tabela Histórico de transações contém 113.443 linhas no total, portanto, a estimativa de 68.336,4 representa uma seletividade de 68336,4/113443 = 0,60238533 para esse predicado. Essa estimativa é obtida usando as informações do histograma para a
TransactionID
coluna e os valores constantes especificados na consulta.Este predicado tem uma seletividade estimada de 68413,0/113443 = 0,60306056 . Novamente, é calculado a partir dos valores constantes do predicado e do histograma do
TransactionDate
objeto de estatísticas.Assumindo que os predicados são completamente independentes, podemos estimar a seletividade dos dois predicados juntos, multiplicando-os. A estimativa de cardinalidade final é obtida multiplicando a seletividade resultante pelas 113.443 linhas na tabela base:
Após o arredondamento, esta é a estimativa de 41.211 vista na consulta original (o otimizador também usa matemática de ponto flutuante internamente).
Não é uma boa estimativa
As colunas
TransactionID
eTransactionDate
têm uma correlação próxima no conjunto de dados AdventureWorks (como as chaves e as colunas de data que aumentam monotonicamente costumam fazer). Essa correlação significa que a suposição de independência é violada. Como consequência, o plano de consulta pós-execução mostra 68.095 linhas em vez das 41.211 estimadas:Sinalizador de rastreamento 4137
A ativação desse sinalizador de rastreamento altera a heurística usada para combinar predicados. Em vez de assumir total independência, o otimizador considera que as seletividades dos dois predicados são próximas o suficiente para que possam ser correlacionadas:
Lembre-se de que o
TransactionID
predicado sozinho estimou 68.336,4 linhas e oTransactionDate
predicado sozinho estimou 68.413 linhas. O otimizador escolheu a menor dessas duas estimativas em vez de multiplicar as seletividades.Esta é apenas uma heurística diferente, é claro, mas que pode ajudar a melhorar as estimativas para consultas com
AND
predicados correlacionados. Cada predicado é considerado para uma possível correlação, e há outros ajustes feitos quando muitasAND
cláusulas estão envolvidas, mas esse exemplo serve para mostrar o básico disso.O equivalente ao sinalizador de rastreamento 4137 no estimador de cardinalidade atual é a
ASSUME_MIN_SELECTIVITY_FOR_FILTER_ESTIMATES
dica de consulta .Estatísticas de várias colunas
Isso pode ajudar em consultas com correlações, mas as informações do histograma ainda são baseadas apenas na coluna inicial das estatísticas. As seguintes estatísticas candidatas de várias colunas, portanto, diferem de maneira importante:
Tomando apenas um deles, podemos ver que a única informação extra são os níveis extras da densidade 'todos'. O histograma ainda contém apenas informações detalhadas sobre a
TransactionDate
coluna.Com essas estatísticas de várias colunas no lugar...
...o plano de execução mostra uma estimativa que é exatamente a mesma de quando apenas as estatísticas de coluna única estavam disponíveis: