Por que o servidor SQL usa paralelismo ao executar esta consulta que usa uma subconsulta, mas não ao usar uma junção? A versão de junção é executada em série e leva cerca de 30 vezes mais para ser concluída.
Versão de entrada: ~30 segundos
Versão da subconsulta: <1 segundo
EDIT: Versões XML do plano de consulta:
Conforme já indicado nos comentários, parece que você precisa atualizar suas estatísticas.
O número estimado de linhas que saem da junção entre
location
etestruns
é muito diferente entre os dois planos.Estimativas do plano de junção: 1
Estimativas do plano de subconsulta: 8.748
O número real de linhas que saem da junção é 14.276.
É claro que não faz sentido intuitivo que a versão de junção deva estimar que 3 linhas devem vir
location
e produzir uma única linha unida, enquanto a subconsulta estima que uma única dessas linhas produzirá 8.748 da mesma junção, mas mesmo assim consegui para reproduzir isso.Isso parece acontecer se não houver cruzamento entre os histogramas quando as estatísticas são criadas. A versão de junção assume uma única linha. E a busca de igualdade única da subconsulta assume as mesmas linhas estimadas que uma busca de igualdade em relação a uma variável desconhecida.
A cardinalidade das execuções de teste é
26244
. Supondo que seja preenchido com três IDs de local distintos, a consulta a seguir estima que8,748
as linhas serão retornadas (26244/3
)Dado que a tabela
locations
contém apenas 3 linhas, é fácil (se assumirmos que não há chaves estrangeiras) criar uma situação em que as estatísticas são criadas e, em seguida, os dados são alterados de uma forma que afeta drasticamente o número real de linhas retornadas, mas é insuficiente para disparar a atualização automática de estatísticas e recompilar o limite.Como o SQL Server obtém o número de linhas que saem dessa junção tão errado, todas as outras estimativas de linha no plano de junção são enormemente subestimadas. Além de significar que você obtém um plano serial, a consulta também recebe uma concessão de memória insuficiente e as classificações e junções de hash se espalham para
tempdb
.Um cenário possível que reproduz as linhas reais versus estimadas mostradas em seu plano está abaixo.
Em seguida, executar as seguintes consultas fornece a mesma discrepância estimada versus real