1概述
Merge join 合并连接。两个集合进行merge join,需要有一个等值的条件,然后需要两个已排序好的集合。

2 one-to-many与many-to-many
2.1 One-to-many
当参与merge join的两个集合中,其中一个集合在等值条件上是具有唯一性(如SELECT * FROM T1 INNER JOIN T2 ON T1.A=T2.B,如果T1在A列上具有唯一性),那么即为one-to-many。主要步骤为:首先从两个集合中各取出一条记录进行比较,如果符合join条件,那么取出该行;否则将值小记录从集合中移除,然后取值小集合的下一行,继续比较。
2.2 many-to many
当参与merge join的两个集合中,没有一个集合在等值条件上具有唯一性时,则采用many-to-many(SELECT * FROM T1 INNER JOIN T2 ON T1.A=T2.B,当列A与列B都不具有唯一性)。主要步骤为:在A和B中都存在A1,A2..An,B1,B2..Bn,那么正常情况下需要为A的每一条记录(A1,A2..An)都要将B中的B1,B2..Bn读取出来,这样浪费性能。所在数据库在处理时,将B中的匹配行储存在tempdb中,如果A中的下一行相等,则读取tempdb中的内容,否则删除tempdb中的数据。
2.3 one-to-many与many-to-many的比较
很显然,one-to-many的效率更高,因为它不需要临时表。那么如何让查询优化器知道我们其中某个集合具有唯一性呢。方法一是:建立聚集索引;二是如distinct、group by操作符。

3排序与索引
数据库几个大的操作之一就是大表的排序,所以使用merge join如果表数据量比较大,并且无索引,那么并不适合merge join。所以当数据量很大,就需要为其添加索引。
4示例
测试数据

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GoodsType]'))
DROP TABLE [dbo].[GoodsType]
GO
--商品类型表
CREATE TABLE dbo.[GoodsType]
(
    id int,
    good_type_name nvarchar(50)
);

INSERT INTO dbo.GoodsType
SELECT 1,'服装'
UNION ALL
SELECT 2,'数码'
UNION ALL
SELECT 3,'家电'

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Goods]'))
DROP TABLE [dbo].[Goods]
GO
--商品类型表
CREATE TABLE dbo.[Goods]
(
    id int,
    good_name nvarchar(50),
    good_type int
);

INSERT INTO dbo.Goods
SELECT 1,'ADT恤',1
UNION ALL
SELECT 2,'AD外套',1
UNION ALL
SELECT 3,'T002电视',2
UNION ALL
SELECT 4,'海尔洗衣机',2
UNION ALL
SELECT 5,'HP222',3

4.1
未建任何索引,执行SQL

SET STATISTICS PROFILE ON
SELECT *
FROM Goods AS GINNER JOIN GoodsType AS GT ON G.good_type=GT.id
OPTION(MERGE JOIN)

说明
1>未建立索引时,需要为两个集合进行排序;
2>虽然在连接条件上唯一,但是未建唯一聚集索引时,为多对多的连接;

4.2
建立非聚集索引,执行SQL

CREATE CLUSTERED INDEX GT ON GOODSTYPE(ID)
CREATE CLUSTERED INDEX G ON GOODS(good_type)SET STATISTICS PROFILE ON
SELECT *
FROM Goods AS GINNER JOIN GoodsType AS GT ON G.good_type=GT.id
OPTION(MERGE JOIN)

说明:
1>建立索引后,执行merge join无排序的开销
2>虽然两个集合都建立了索引,并且连接的关键字也无重复,但还是多对多的连接,因为优化器不知道它是唯一的。

4.3
为其中一个集合建立唯一聚集索引,执行SQL

DROP INDEX GT ON GOODSTYPE
CREATE UNIQUE CLUSTERED INDEX GUT ON GOODSTYPE(ID)SET STATISTICS PROFILE ON
SELECT *
FROM Goods AS GINNER JOIN GoodsType AS GT ON G.good_type=GT.id
OPTION(MERGE JOIN)

说明:
1>为其中的一个集合建立唯一聚集索引时,此时的连接为一对一的连接(执行计划中无一对一连接的概念)

5总结
当不适合使用nested join时,可以考虑使用merge join。在使用merge join时,需要注意两个概念:一是排序,最好是索引排序,否则大数据量的实时排序会增加太多的成本;二是连接方式,是一对多还是多对多,如果关键字不重复,可以建立唯一聚集索引,即尽量使用一对多的连接。

其中set statistics profile on //打开执行计划,执行计划的列说明如下:

Rows:执行计划的每一步返回的实际行数。

Executes:执行计划的每一步被运行了多少次。

StmtText:执行计划的具体内容。执行计划以一棵树的形式显示。每一行,都是运行的一步,都会有结果集返回,也都会有自己的cost。

EstimateRows:SQL Server根据表格上的统计信息,预估的每一步的返回行数。在分析执行计划时,我们会经常将Rows和EstimateRows这两列做对比,先确认SQL Server预估得是否准确。
EstimateIO:SQL Server根据EstimateRows和统计信息里记录的字段长度,预估的每一步会产生的I/O cost。

EstimateCPU:SQL Server根据EstimateRows和统计信息里记录的字段长度,以及要做的事情的复杂度,预估的每一步会产生的CPU cost。

TotalSubtreeCost:SQL Server根据EstimateIO和EstimateCPU通过某种计算公式,计算出的每一步执行计划子树cost(包括这一步自己的cost和它的所有下层步骤的cost总和)。

Warnings:SQL Server在运行每一步时遇到的警告,例如,某一步没有统计信息支持cost预估等。

Parallel:执行计划的这一步是不是使用了并行的执行计划。

本文章参考自:http://www.cnblogs.com/dataadapter/archive/2012/08/27/2658784.html

MS SQL SERVER 中merge join合并连接介绍(转)相关推荐

  1. 游标sql server_了解游标并将其替换为SQL Server中的JOIN

    游标sql server Relational database management systems including SQL Server are very good at processing ...

  2. sql oracle 自增长字段,在Oracle、MySQL、MS SQL Server中创设自动增长字段

    在Oracle.MySQL.MS SQL Server中创建自动增长字段 好吧,今天面试有道题,要各个数据库怎么建立自增长字段,顺便复习一下吧,最近面试很多数据库问题... 一:Oracle Orac ...

  3. SQL Server中追踪器Trace的介绍和简单使用

    原文:SQL Server中追踪器Trace的介绍和简单使用 一.What is Trace? 对于SQL Profiler这个工具相信大家都不是很陌生,没用过的朋友可以在SQL Server Man ...

  4. 在SQL Server中使用JOIN更新表?

    我想更新在其他表上进行联接的表中的列,例如: UPDATE table1 a INNER JOIN table2 b ON a.commonfield = b.[common field] SET a ...

  5. MS SQL Server中的CONVERT日期格式化大全

    來源:http://www.knowsky.com/345490.html CONVERT 将某种数据类型的表达式显式转换为另一种 数据类型.由于某些需求经常用到取日期格式的不同.现以下可在 SQL ...

  6. [MSSQL]SQL Server中的RAND函数的介绍和区间随机数值函数的实现

    转自:http://www.cnblogs.com/dzy863/p/5063558.html 工作中会遇到SQL Server模拟数据生成以及数值列值(如整型.日期和时间数据类型)随机填充等等任务, ...

  7. MS SQL SERVER 中几个函数的用法

    1.STUFF 将第一个参数,从第start位置开始的length个字符(包含第start位置,位置从1开始),用第四个参数替换. Syntax ( character_expression , st ...

  8. SQL Server中,with as使用介绍

    一.WITH AS的含义      WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到.有的时候 ...

  9. mysql的datepart函数_MySQL中的 DATE_FORMAT 与 SQL Server中的 DATEPART()函数使用介绍

    本小白最近学习MySQL,因为之前是已经有学过微软大佬的SQL Server所以自认为理解的还是稍快的(滑鸡),好了说正事. 今天在写一个查询语句时,需要用到 一个日期函数:DATEPART( ) 因 ...

最新文章

  1. Android setOnItemClickListener cannot be used with a spinner
  2. 18常用web开发 浮动层、提示层代码下载
  3. iPhone开发:09年开发领域的最热看点!
  4. PDF文档怎么提取其中一页
  5. sql server检查临时表是否存在
  6. ubuntu android2.3 emulator,Android Studio 2.3 Ubuntu 16.10 emulator do not start
  7. 虚拟机无法开机数据恢复 (建议在做之前做测试,数据双重备份)
  8. 485转232转换器产品介绍及性能参数介绍
  9. 局部变量竟然比全局变量快 5 倍?
  10. Jupyter Notebook的安装和使用
  11. TensorFlow十三 LSTM练习
  12. 计算机启动单元,快速启动计算机系统的方法和计算机的启动系统与流程
  13. 三年Java开发经验,必须要掌握的知识技能树有哪些?
  14. 组件化开发Android应用及SDK
  15. 高通骁龙X55 5G modem信息图和骁龙X55调制解调器简介
  16. 【Origin】羡旁人
  17. ValueError: could not convert string to float:
  18. vue使用高德地图搜索地址添加标记marker,定位,拖拽选址功能
  19. Linux下帆软报表部署
  20. 【智能优化算法】基于沙猫群优化算法求解单目标优化问题附matlab代码

热门文章

  1. 复工别慌,这里有 24 个渠道可以买到口罩
  2. arcgis风向_arcgis制作风或水流速流向图
  3. 2017淮北计算机会考,2017年安徽淮北高中会考报名网站:淮北教育局
  4. Matlab 均分圆形生成点
  5. 张小龙2011年饭否日记
  6. 基于校园网的SSM高校财务预约报账J2EE报销系统javaweb
  7. 2019牛客暑期多校训练营(第一场)B Integration 裂项相消 + 积分
  8. 现在的程序员真的都找不到女朋友了??!!!
  9. JAVA SE8 OCA/OCP和PL/SQL OCA/OCP认证书籍推荐
  10. MAC 编译提示autom4te: need GNU m4 1.4 or later: /usr/bin/m4