sql-server – 哈希密钥探测和残差

前端之家收集整理的这篇文章主要介绍了sql-server – 哈希密钥探测和残差前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
说,我们有这样的查询
select a.*,b.*
from 
a join b
on a.col1=b.col1
and len(a.col1)=10

假设上面的查询使用Hash Join并且有一个残差,则探测键将为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,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不能仅使用探测列?为什么必须使用相同的列作为残差来再次过滤行?

测试数据的参考:

> Hash Join (Craig Freedman’s SQL Server Blog)

解决方法@H_502_30@
如果连接在单个列上,类型为tinyint,smallint或integer *,并且如果两个列都被约束为NOT NULL,则哈希函数是“完美的” – 意味着没有机会发生哈希冲突,并且查询处理器不必再次检查值以确保它们真正匹配.

否则,您将看到残差,因为哈希桶中的项目将进行匹配测试,而不仅仅是哈希函数匹配.

您的测试没有为列指定NULL或NOT NULL(顺便说一下,这是一种不好的做法),因此您似乎使用的数据库中默认为NULL.

更多信息,请参阅Dmitry Pilugin在Join Performance,Implicit Conversions,and ResidualsHash Join Execution Internals发表的文章.

*其他限定类型是bit,smalldatetime,smallmoney和(var)char(n),用于n = 1和二进制排序规则

猜你在找的MsSQL相关文章