Sonda de chaves hash e residual

21

Digamos, temos uma consulta como esta:

select a.*,b.*
from 
a join b
on a.col1=b.col1
and len(a.col1)=10

Supondo que a consulta acima use uma junção de hash e tenha um resíduo, a chave do probe será col1e o restante será len(a.col1)=10.

Mas, ao seguir outro exemplo, pude ver a sonda e o residual como a mesma coluna. Abaixo está uma elaboração sobre o que estou tentando dizer:

Inquerir:

select *
from T1 join T2 on T1.a = T2.a 

Plano de execução, com sonda e residual destacados:

insira a descrição da imagem aqui

Dados de teste:

create table T1 (a int, b int, x char(200))
create table T2 (a int, b int, x char(200))

set nocount on
declare @i int
set @i = 0
while @i < 1000
  begin
      insert T1 values (@i * 2, @i * 5, @i)
    set @i = @i + 1
  end

declare @i int
set @i = 0
while @i < 10000
  begin
    insert T2 values (@i * 3, @i * 7, @i)
    set @i = @i + 1
  end

Questão:

Como uma sonda e um resíduo podem ser a mesma coluna? Por que o SQL Server não pode usar apenas a coluna de análise? Por que ele precisa usar a mesma coluna que um resíduo para filtrar linhas novamente?

Referências para dados de teste:

TheGameiswar
fonte

Respostas:

22

Se a junção é em uma única coluna escrita como tinyint, smallintou integer* e se ambas as colunas são obrigados a ser NOT NULL, a função hash é 'perfeito' - o que significa que não há chance de uma colisão de hash, e o processador de consulta não precisa de verificação os valores novamente para garantir que eles realmente correspondam.

Caso contrário, você verá um resíduo quando os itens no bucket de hash forem testados para uma correspondência, não apenas uma correspondência de função de hash.

Seu teste não especifica NULLou NOT NULLpara as colunas (uma prática recomendada, a propósito); portanto, parece que você está usando um banco de dados onde NULLé o padrão.

Mais informações em meu post Ingressar no desempenho, conversões implícitas e residuais e Hash Join Execution Internals por Dmitry Pilugin.


* Outros tipos de qualificação são bit , smalldatetime , smallmoney e (var) char (n) para n = 1 e agrupamento binário

Paul White diz que a GoFundMonica
fonte