Hash Keys Probe und Residuum

21

Angenommen, wir haben eine Abfrage wie die folgende:

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

Angenommen, die obige Abfrage verwendet einen Hash-Join und hat einen Residuum, dann ist der Prüfschlüssel col1und der Residuum len(a.col1)=10.

Aber als ich ein anderes Beispiel durchging, konnte ich sehen, dass sowohl die Sonde als auch das Residuum dieselbe Spalte waren. Nachfolgend eine Ausarbeitung dessen, was ich versuche zu sagen:

Abfrage:

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

Ausführungsplan mit hervorgehobener Sonde und Restmenge:

Bildbeschreibung hier eingeben

Testdaten:

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

Frage:

Wie kann eine Sonde und ein Residuum dieselbe Spalte sein? Warum kann SQL Server nicht nur die Testspalte verwenden? Warum muss dieselbe Spalte als Residuum verwendet werden, um die Zeilen erneut zu filtern?

Referenzen für Testdaten:

TheGameiswar
quelle

Antworten:

22

Befindet sich der Join in einer einzelnen Spalte tinyint, die mit smallint, oder integer* gekennzeichnet ist, und müssen beide Spalten mit * angegeben werden NOT NULL, ist die Hash-Funktion "perfekt". Dies bedeutet, dass keine Hash-Kollision möglich ist und der Abfrageprozessor keine Überprüfung durchführen muss die Werte erneut, um sicherzustellen, dass sie wirklich übereinstimmen.

Andernfalls wird ein Residuum angezeigt, wenn Elemente im Hash-Bucket auf eine Übereinstimmung geprüft werden, nicht nur auf eine Übereinstimmung mit einer Hash-Funktion.

In Ihrem Test sind keine NULLoder nur NOT NULLfür die Spalten angegeben (im Übrigen eine schlechte Vorgehensweise). Sie verwenden also anscheinend eine Datenbank, in der NULLdie Standardeinstellung verwendet wird.

Weitere Informationen finden Sie in meinem Beitrag " Join-Leistung", "Implizite Konvertierungen" und " Internals für Rest- und Hash-Join-Ausführung" von Dmitry Pilugin.


* Andere qualifizierende Typen sind bit , smalldatetime , smallmoney und (var) char (n) für n = 1 und binäre Kollatierung

Paul White sagt GoFundMonica
quelle