</h1>
<div class="clear"></div>
<div class="postBody">
<div id="cnblogs_post_body" class="blogpost-body blogpost-body-html">
简介
在 SQL Server 2012 在一些特殊的例子下会看到下面的图标:
Hash Join分为两个阶段,分别为生成和探测阶段。
首先是生成阶段,将输入源中的每一个条目经过散列函数的计算都放到不同的Hash Bucket中,其中Hash Function的选择和Hash Bucket的数量都是黑盒,通常来讲,查询优化器都会使用连接两端中比较小的哪个输入集来作为第一阶段的输入源。
接下来是探测阶段,对于另一个输入集合,同样针对每一行进行散列函数,确定其所应在的Hash Bucket,在针对这行和对应Hash Bucket中的每一行进行匹配,如果匹配则返回对应的行。
通过了解哈希匹配的原理不难看出,哈希匹配涉及到散列函数,所以对CPU的消耗会非常高,此外,在Hash Bucket中的行是无序的,所以输出结果也是无序的。
示例演示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
IF OBJECT_ID(
'dbo.Tbl10'
)
IS
NOT
NULL
DROP
TABLE
dbo.Tbl10;
CREATE
TABLE
dbo.Tbl10(
Id
INT
IDENTITY(1,1),
Val
INT
,
Fill
CHAR
(7000)
NOT
NULL
DEFAULT
REPLICATE(
'Fill'
,1750)
);
IF OBJECT_ID(
'dbo.Tbl100'
)
IS
NOT
NULL
DROP
TABLE
dbo.Tbl100;
CREATE
TABLE
dbo.Tbl100(
Id
INT
IDENTITY(1,1),
Val
INT
,
Fill
CHAR
(7000)
NOT
NULL
DEFAULT
REPLICATE(
'Fill'
,1750)
);
INSERT
INTO
dbo.Tbl10(Val)
SELECT
TOP
(10) 1+ROW_NUMBER()OVER(
ORDER
BY
(
SELECT
1))%100
FROM
sys.all_columns A, sys.all_columns B, sys.all_columns C;
INSERT
INTO
dbo.Tbl100(Val)
SELECT
TOP
(100) ROW_NUMBER()OVER(
ORDER
BY
(
SELECT
1))
FROM
sys.all_columns A, sys.all_columns B, sys.all_columns C;
SELECT
index_type_desc, alloc_unit_type_desc, index_depth, page_count, record_count
FROM
sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(
'dbo.Tbl10'
),
NULL
,
NULL
,
'SAMPLED'
);
SELECT
index_type_desc, alloc_unit_type_desc, index_depth, page_count, record_count
FROM
sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(
'dbo.Tbl100'
),
NULL
,
NULL
,
'SAMPLED'
);
|
使用hash join执行下面查询
1
2
3
4
5
6
7
8
|
SET
STATISTICS
IO
ON
;
GO
SELECT
*
FROM
dbo.Tbl100 A
INNER
HASH
JOIN
dbo.Tbl10 B
ON
A.Val = B.Val;
GO
SET
STATISTICS
IO
OFF
;
|
查看统计信息:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Tbl10'. Scan count 1, logical reads 10, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Tbl100'. Scan count 1, logical reads 100, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
优缺点:
•所有逻辑连接类型都可以处理。
•它确实需要一个相当大的内存量,足够大,以适应整个左侧输入。(可能会在tempdb中)
•在创建哈希索引的整个过程中,没有一行将返回。
在连接条件中至少有一列需要使用一个相等的比较。
因为昂贵的建立阶段,这是最资源密集的连接算法。然而,一旦哈希表是建立的,这个连接算法可以很快。对于没有可用的索引的大表,在探测阶段的时间节省将超过建设阶段的额外费用。然而,记住,因为大量的内存需求,只有极少数的这些可以运行在同一时间。
<div id="blog_post_info">
<div class="clear"></div>
<div id="post_next_prev">
<a href="https://www.cnblogs.com/qianlixing/p/4764680.html" class="p_n_p_prefix">« </a> 上一篇: <a href="https://www.cnblogs.com/qianlixing/p/4764680.html" data-featured-image="" title="发布于 2015-08-29 23:49">SQL Server的三种物理连接之Merge join(二)</a>
<br>
<a href="https://www.cnblogs.com/qianlixing/p/4785223.html" class="p_n_p_prefix">» </a> 下一篇: <a href="https://www.cnblogs.com/qianlixing/p/4785223.html" data-featured-image="" title="发布于 2015-09-06 13:06">SQL Server查看表信息</a>
</div><!--end: topics 文章、评论容器-->