SQL Server nested loop join 效率试验

从很多网页上都看到,SQL Server有三种Join的算法, nested loop join, merge join, hash join. 其中最常用的就是nested loop join.

在介绍nested loop join的很多文章里,都提到如果两个表做nested loop join,取行数较小的表作为外循环表,行数较多的表作为内循环表, join的效率会比较高.

其中之一的原因是如果内循环表做join的列上有合适的索引的话,那么外循环的每一条输入数据可以做索引的seek,这样就不会把整个的内循环表读一遍,尤其是内循环表比较大的话,节省的成本更高. 但是如果内外循环表都没有合适的索引,这样做join,为什么效率也比较高呢?

举个例子,外循环表有10行数据,内循环表有1000行数据,按照nested loop join 的算法,外循环表中取一条,和内循环表的所有数据匹配一遍,输出匹配的数据行. 这样就是要进行10*1000=10000次的匹配; 如果反过来,外循环1000行,内循环10行,那么外循环表中取一条数据,内循环表中遍历10行数据,总计也是1000*10=10000次. 粗看来都一样啊..为什么都说外循环表小的话,效率高呢?  做个试验看看吧.

use tempdb
go
--创建两个表,测试nested loop join的效率
CREATE TABLE TempA (string VARCHAR(1000))
go
CREATE TABLE TempB (string VARCHAR(1000))
go
--插入数据, 让表TempA中的数据刚好存在1页里
INSERT INTO TempA SELECT REPLICATE(‘a‘ , 1000)
INSERT INTO TempA SELECT REPLICATE(‘b‘ , 1000)
INSERT INTO TempA SELECT REPLICATE(‘c‘ , 1000)
INSERT INTO TempA SELECT REPLICATE(‘d‘ , 1000)
INSERT INTO TempA SELECT REPLICATE(‘e‘ , 1000)
INSERT INTO TempA SELECT REPLICATE(‘f‘ , 1000)
INSERT INTO TempA SELECT REPLICATE(‘g‘ , 1000)

--往TempB中插入数据,让TempB的数据是TempA的100倍
insert into TempB select * from TempA
go 100
--检验一下表TempA 和 TempB的大小
set statistics io on
select * from TempA
select * from TempB
--返回的结果如下:
/*
Table‘TempA‘. Scan count 1, logical reads 1
Table‘TempB‘. Scan count 1, logical reads 100
*/
--由此可以看出表TempA有7行,存储在1个页; TempB有700行,存储在100个页里.

--执行以下查询,将TempA作为外循环表,TempB作为内循环表,看看执行的成本如何
SELECT *FROM TempA a INNER LOOP JOIN TempB b
ONa.string = b.string OPTION (FORCE order)
/*
Table‘TempB‘. Scan count 1, logical reads 700
Table‘TempA‘. Scan count 1, logical reads 1
*/

从结果可以看出从TempA读了1个页,从TempB读了700个页,合计701个逻辑读, 也就是说外循环的表,做一次全表读,有多少页就有多少逻辑读; 内循环的表,对应外循环表的每1条记录,都要读一次全表读,即7乘以100,700个逻辑读.

如果按照这个规律,调换内外循环表的位置,得到的逻辑读应该是 TempB的一次全表读, 100个逻辑读加上700行乘以TempA的全表读(1页),就是700个逻辑读,合计是800个逻辑读.

--对调一下join的顺序,再看看执行成本:
SELECT *FROM tempb b INNER LOOP JOIN tempa a
ONa.string = b.string OPTION(FORCE ORDER)
/*
Table‘TempA‘. Scan count 1, logical reads 700
Table‘TempB‘. Scan count 1, logical reads 100
*/

果不其然,和预计的一样.

所以在这种假定的情况下,外循环表较小的话,join的成本更低.

实验的表结构比较特殊,如果往一般情况推演一下,可以做出这样的假设:

假设表X有a页,平均每页有b行,表Y有c页,平均每页有d行.
则以表X为外循环,表Y为内循环,则nested loop join的成本是 a+(a*b*c), 而已表Y为外循环,表X为内循环,则nested loop join的成本是 c+(c*d*a)

原文地址:https://www.cnblogs.com/littlewrong/p/9042987.html

时间: 2024-10-17 09:19:33

SQL Server nested loop join 效率试验的相关文章

深入理解Oracle表(3):三大表连接方式详解之Nested loop join和 Sort merge join

深入理解Oracle表(3):三大表连接方式详解之Nested loop join和 Sort merge join 分类: Oracle 基础管理 Oracle SQL 开发2013-01-28 00:33 2536人阅读 评论(1) 收藏 举报 关系数据库技术的精髓就是通过关系表进行规范化的数据存储       并通过各种表连接技术和各种类型的索引技术来进行信息的检索和处理       这里Think愿意和大家一起来学习分享Oracle的三大表连接技术              在早期版本,

join中级篇---------hash join & merge join & nested loop Join

嵌套循环连接(Nested Loop Join) 循环嵌套连接是最基本的连接,正如其名所示那样,需要进行循环嵌套,嵌套循环是三种方式中唯一支持不等式连接的方式,这种连接方式的过程可以简单的用下图展示: 图1.循环嵌套连接的第一步 图2.循环嵌套连接的第二步 由上面两个图不难看出,循环嵌套连接查找内部循环表的次数等于外部循环的行数,当外部循环没有更多的行时,循环嵌套结束.另外,还 可以看出,这种连接方式需要内部循环的表有序(也就是有索引),并且外部循环表的行数要小于内部循环的行数,否则查询分析器就

禁用nested loop join里的spool

禁用nested loop join里的spool 转载自: https://blogs.msdn.microsoft.com/psssql/2015/12/15/spool-operator-and-trace-flag-8690/ https://answers.sqlperformance.com/questions/698/lazy-spool.html 在nested loop join里常常会看到一个spool操作符 这个spool 又名'performance spool',目的是

1122MySQL性能优化之 Nested Loop Join和Block Nested-Loop Join(BNL)

转自http://blog.itpub.net/22664653/viewspace-1692317/ 一 介绍  相信许多开发/DBA在使用MySQL的过程中,对于MySQL处理多表关联的方式或者说性能一直不太满意.对于开发提交的含有join的查询,一般比较抗拒,从而建议将join拆分,避免join可能带来的性能问题,同时也增加了程序和DB的网络交互.5.5 版本之前,MySQL本身只支持一种表间关联方式,就是嵌套循环(Nested Loop).如果关联表的数据量很大,则join关联的执行时间

oracle多表连接方式Hash Join Nested Loop Join Merge Join

在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理. 一.连接方式:        嵌套循环(Nested  Loops (NL))      (散列)哈希连接(Hash Join (HJ))    (归并)排序合并连接(Sort Merge Join (SMJ) ) 二.连接说明:    1.Oracle一次只能连接两个表.不管查询中有多少个表,Oracle 在连接中一次仅能操作两张表.    2.当执行多个表的连接时,优化

SQL Server基础:Join

3.Join(麻蛋  废话不多说 有图有真相) 测试数据脚本 1 CREATE TABLE Atable 2 ( 3 S# INT, 4 Sname nvarchar(32), 5 Sage INT, 6 Sfrom nvarchar(8) 7 ) 8 9 10 insert into Atable 11 select 1,N'刘一',18,N'A' union all 12 select 2,N'钱二',19,N'A' union all 13 select 3,N'张三',17,N'A' u

SQL Server三种表连接原理

http://msdn.microsoft.com/zh-cn/library/dn144699.aspx 简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge Join,Hash Join这三种物理连接中的一种.理解这三种物理连接是理解在表连接时解决性能问题的基础,下面我来对这三种连接的原理,适用场景进行描述. 嵌套循环连接(Nested Loop J

Sql Server 优化 SQL 查询:如何写出高性能SQL语句

1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用 “全表扫描”方式. 可见,执行计划并不是固定的,它是“个性化的”.产生一个正确的“执行计划”有两点很重要: (1)    SQL语句是否清晰地告诉查询优化器它想干什么? (2)

SQL Server优化查询

1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用 “全表扫描”方式.可见,执行计划并不是固定的,它是“个性化的”.产生一个正确的“执行计划”有两点很重要: (1)SQL语句是否清晰地告诉查询优化器它想干什么?(2)查询优化器得到