ハッシュキープローブと残差


21

次のようなクエリがあるとします。

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

上記のクエリがハッシュ結合を使用し、残差があると仮定すると、プローブキーはにcol1なり、残差はになりますlen(a.col1)=10

しかし、別の例を見ると、プローブと残差の両方が同じ列であることがわかりました。以下は、私が言おうとしていることの詳細です。

クエリ:

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

プローブと残差が強調表示された実行計画:

ここに画像の説明を入力してください

テストデータ:

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

質問:

プローブと残差を同じカラムにするにはどうすればよいですか?SQL Serverがプローブ列のみを使用できないのはなぜですか?行を再度フィルタリングするために、同じ列を残差として使用する必要があるのはなぜですか?

テストデータの参照:

回答:


22

参加した場合である単一の列が入力された上でのようにtinyintsmallintまたはinteger*両方の列があるように制約されている場合やNOT NULL、ハッシュ関数は、「完全」である-ハッシュ衝突の見込みがないことを意味し、クエリプロセッサは確認する必要はありません。値を再度一致させて、実際に一致するようにします。

そうしないと、ハッシュバケット内のアイテムが、ハッシュ関数の一致だけでなく一致についてテストされるため、残差が表示されます。

テストでは、列を指定NULLまたはNOT NULL列に対して指定していません(ちなみに悪い習慣です)のでNULL、デフォルトのデータベースを使用しているようです。

私の投稿の詳細については、Dmitry PiluginによるJoin Performance、Implicit Conversions、ResidualsおよびHash Join Execution Internalsを参照してください。


*その他の修飾タイプは、n = 1およびバイナリ照合のbitsmalldatetimesmallmoney、および(var)char(n)です

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.