As associações adaptáveis de modo de lote fazem parte de uma família de recursos no processador de consultas de 2017 que consiste em:
- Junções adaptáveis do modo de lote
- Execução intercalada
- Feedback de concessão de memória do modo de lote
Então, como funcionam as Adaptive Joins?
Junções adaptáveis do modo de lote
Para associações adaptáveis de modo em lote, o objetivo é não fixar a opção de associação a um tipo específico em tempo de compilação.
Quando disponíveis, Adaptive Joins permitem que o otimizador escolha entre junções de loops aninhados e junções de hash com base nos limites de linha em tempo de execução.
Neste momento, Merge Joins não são consideradas. A pura especulação é que a necessidade de classificar os dados ou a necessidade de injetar uma classificação no plano adicionaria muita sobrecarga ao alterar o curso de uma consulta.
Quando ocorrem as junções adaptativas do modo de lote?
Neste momento, o processamento de consultas no Modo Lote requer a presença de um índice ColumnStore. Eles também exigem, bem, uma junção e um índice que permite a escolha de um loop aninhado ou uma junção de hash.
Como saber se meu Join é Adaptável?
Os planos de consulta para junções adaptativas são bastante distintos.
O operador Adaptive Join é novo no SQL Server 2017 e atualmente possui as seguintes propriedades nos planos de execução reais.
Operação Física: Junção Adaptativa
Tipo de junção real: será correspondência de hash ou loops aninhados
Adaptive Threshold Rows: indica o ponto de inflexão quando o tipo de junção mudará para Hash Match
Is Adaptive: True para Adaptive Joins
Tipo de junção estimado: bastante auto-explicativo!
Em um plano estimado ou armazenado em cache, há muito menos informações:
Mais notavelmente, o tipo de junção real está ausente.
O que interrompe as junções adaptativas do modo de lote?
Para monitorar isso, há uma sessão de evento estendido chamada
adaptive_join_skipped
, e tem os seguintes motivos para ignorar uma associação adaptativa do modo de lote:Além disso, as Junções Adaptativas do Modo de Lote podem ser ignoradas por outros motivos. Veja essas duas consultas por exemplo:
Eles são idênticos, exceto que a segunda consulta seleciona a
DisplayName
coluna, que tem um tipo deNVARCHAR(40)
.A junção adaptativa do modo de lote é ignorada para a segunda consulta, mas nenhum motivo é registrado na sessão XE. Parece que os dados de string continuam sendo o inimigo inabalável dos índices ColumnStore.
Existem outros padrões de consulta que não conseguem Adaptive Joins, que também não acionam eventos.
Alguns exemplos:
CROSS APPLY
com umTOP
OUTER APPLY
eajsrExchangeTypeNãoSuportado
Uma coisa que acionará esse evento parece ser a presença de um operador Repartição Streams. Nesta consulta, o tipo de particionamento é Hash Match. Agradecimentos especiais ao Ser Celestial Intergaláctico disfarçado de um humilde blogueiro conhecido como Paul White pela bizarra pergunta.
eajsrHJorNLJNotFound
Nenhuma consulta acionou este XE ainda. O que não funciona:
Dica de mesclagem
Os padrões de consulta que excluem o tipo de junção, por exemplo, junções de Hash e Merge requerem pelo menos um predicado de igualdade. Escrevendo uma junção
>=
e<=
não aciona o evento.eajsrInvalidAdaptiveThreshold
Esse evento pode ser acionado por várias consultas
TOP
,FAST N
e .OFFSET/FETCH
aqui estão alguns exemplos:Em algumas circunstâncias, eles também podem ser acionados por consultas de estilo de paginação:
eajsrMultiConsumerSpool
Nenhum padrão de consulta conhecido acionou este evento ainda.
O que não acionou até agora:
CTEs recursivos
Conjuntos de agrupamento/cubo/agrupamento
PIVOT e UNPIVOT
Funções de janela
eajsrOuterCardMaxOne
Alguns tipos diferentes de consultas acionaram esse evento. Uma junção derivada com um
TOP 1
e uma junção combinada com uma cláusula WHERE com um predicado de igualdade em uma coluna exclusiva:eajsrOuterSideParallelMarked
Um tipo de consulta que pode acionar esse evento é um CTE recursivo.
A razão aqui parece ser que a parte recursiva do CTE, que causa uma zona serial no plano, não permite a escolha de junção adaptativa do modo de lote.
eajsrUnMatchedOuter
Este é o mais comum e parece ocorrer quando um índice é usado para a junção que não pode suportar uma busca. Por exemplo, esta consulta causa uma pesquisa de chave:
A consulta resultante escolhe uma junção de loops aninhados de modo de linha para executar a pesquisa de chave e as junções de tabela, o que aciona o evento.
Outro exemplo é uma consulta que ignora o índice restrito não clusterizado em favor do PK/CX. Neste caso, o PK/CX não conduz com
OwnerUserId
, então a única opção de junção é uma Junção de Hash.Em ambos os casos, o "unmatched outer" parece indicar que o índice escolhido não cobre suficientemente nossa consulta.
As junções adaptativas do modo de lote funcionam com várias junções?
Sim, mas no momento da redação deste artigo, parece haver uma limitação:
A associação de um índice ColumnStore a vários índices de armazenamento de linha produzirá várias associações adaptáveis, enquanto uma associação entre vários índices ColumnStore não será adaptável.
Por exemplo, essas duas consultas
A primeira consulta une um índice ColumnStore (em Users) a dois índices Row Store em Posts e Comentários. Isso produz dois operadores Adaptive Join.
A segunda consulta une duas tabelas ColumnStore (Users e Comments) a uma tabela Row Store (Posts) e gera uma Adaptive Join.
Existe alguma sobrecarga nas Associações Adaptativas do Modo em Lote?
Sim, todos os planos de junção adaptativa do modo de lote recebem uma concessão de memória. Isso nem sempre é o caso da junção de loops aninhados, a menos que eles recebam a otimização de pré-busca de loops aninhados. A concessão de memória é para dar suporte a um Hash Join, caso o plano exija um com base nos limites de linha.