Ao diagnosticar consultas do SQL Server 2008 R2 com baixa estimativa de cardinalidade (apesar da indexação simples, estatísticas atualizadas etc.) e, portanto, com planos de consultas ruins, encontrei um artigo da KB talvez relacionado: CORREÇÃO: Desempenho ruim ao executar uma consulta que contém predicados AND correlacionados no SQL Server 2008 ou no SQL Server 2008 R2 ou no SQL Server 2012
Eu posso adivinhar o que o artigo da KB quer dizer com "correlacionado", por exemplo, o predicado nº 2 e o predicado nº 1 têm como alvo as mesmas linhas.
Mas não sei como o SQL Server sabe sobre essas 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 duas razões:
- para determinar quais das minhas tabelas e consultas podem ser aprimoradas usando esse hotfix
- para saber o que devo fazer na indexação, estatística, etc., para afetar o número 1
fonte
Statistics objects on multiple columns also store statistical information about the correlation of values among the columns
Respostas:
Considere o plano simples de consulta e execução AdventureWorks mostrado abaixo. A consulta contém predicados conectados
AND
. A estimativa de cardinalidade do otimizador é 41.211 linhas:Usando estatísticas padrão
Dadas apenas estatísticas de coluna única, o otimizador produz essa estimativa estimando a cardinalidade de cada predicado separadamente e multiplicando as seletividades resultantes juntas. Essa 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 68.336,4 representa uma seletividade de 68336,4 / 113443 = 0,60238533 para esse predicado. Essa estimativa é obtida usando as informações do histograma da
TransactionID
coluna e os valores constantes especificados na consulta.Esse 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 estatístico.Supondo que os predicados sejam completamente independentes, podemos estimar a seletividade dos dois predicados juntos, multiplicando-os. A estimativa final da cardinalidade é obtida multiplicando a seletividade resultante pelas 113.443 linhas na tabela base:
Após o arredondamento, esta é a estimativa 41.211 vista na consulta original (o otimizador também usa matemática de ponto flutuante internamente).
Não é uma ótima estimativa
As colunas
TransactionID
eTransactionDate
têm uma estreita correlação no conjunto de dados do AdventureWorks (como geralmente aumentam monotonicamente chaves e colunas de data). Essa correlação significa que a suposição de independência é violada. Como conseqüência, o plano de consulta pós-execução mostra 68.095 linhas em vez dos 41.211 estimados:Bandeira de rastreamento 4137
A ativação desse sinalizador de rastreamento altera as heurísticas usadas 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.Essa é apenas uma heurística diferente, é claro, mas que pode ajudar a melhorar as estimativas de 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.Estatísticas de várias colunas
Isso pode ajudar nas consultas com correlações, mas as informações do histograma ainda são baseadas apenas na coluna principal das estatísticas. As seguintes estatísticas de várias colunas candidatas diferem, portanto, de uma maneira importante:
Tomando apenas um deles, podemos ver que a única informação extra são os níveis extras da densidade 'all'. 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 exatamente igual a quando apenas as estatísticas de coluna única estavam disponíveis:
fonte