たとえば、次のようなクエリがあるとします。
_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がプローブ列のみを使用できないのはなぜですか?行を再度フィルタリングするために、同じ列を残差として使用する必要があるのはなぜですか?
テストデータの参照:
結合がtinyint
、smallint
、またはinteger
*として入力された単一の列にあり、両方の列がNOT NULL
に制約されている場合、ハッシュ関数は「完全」-ハッシュの衝突の可能性がないことを意味します。クエリプロセッサは、値が本当に一致することを確認するために値を再度チェックする必要はありません。
それ以外の場合、ハッシュバケット内のアイテムは、ハッシュ関数の一致だけでなく、一致についてテストされるため、残差が表示されます。
テストでは列にNULL
またはNOT NULL
を指定していません(ところで、悪い習慣です)。したがって、NULL
がデフォルトのデータベースを使用しているようです。
詳細については、投稿 Join Performance、Implicit Conversions、and Residuals and Hash Join Execution Internals by Dmitry Piluginを参照してください。
*他の修飾タイプはbit、smalldatetime、smallmoney、および(var)char(n)n = 1およびバイナリ照合