科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道通往性能优化的JOIN方法说明(2)

通往性能优化的JOIN方法说明(2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

看到很多朋友对数据库的理解、认识还是没有突破一个瓶颈,而这个瓶颈往往只是一层窗纸,越过了你将看到一个新世界。 @[8 *G

作者:赛迪网技术社区 来源:赛迪网技术社区 2007年8月26日

关键字: 数据库 优化 SQL Server SQL Server 各版本

  • 评论
  • 分享微博
  • 分享邮件

1.3 查看执行计划方法 _nk{_`ZP  
_w*))\  
移到文章最前面。 (FTA\Ry9  
0j*:$/  
1.4 执行步骤 z(]]vmvQ  
qG5"'\]mh  
下面是示例SQL的执行计划图。nested loop操作的右边,位于上面的是outer input,位于下面的是inner input。你不能够根据join中哪个表出现在前面来确定outer input和inner input关系,而必须从执行计划中来确定,因为SQL Server会自动选择哪个作为inner input。 &n7/SE  
.Wx:K1  
L1v- =5:4@  

通往性能优化的JOIN方法说明(2)  3eBP  
图1 48 Ib  
R,s]ZQuh  
a) 对tableA执行Table Scan操作。这个操作的输入是tableA表中的数据,这些数据位于磁盘上,操作过程中被加载到内存;输出是符合条件的记录集,将作为b)的outer input。在这个操作中,tableA.col1=?的条件会被使用。 38+~C X  
K 8LWFXF  
b) 执行上面伪代码描述的nested loop操作。对a)中的每个输出记录,执行步骤c)。 y-V15|2F  
QbWW3;,wf  
c) 对tableB执行Clustered Index Seek操作。这个操作是在nested loop循环里面执行的,输入是tableB表的聚集索引数据。它使用tableB.col1=rowA.col1和tableB.col2=?这两个条件,从tableB的聚集索引中选择符合条件的结果。 J sHf8jQ  
C@X/h!bj  
d) 构造返回结果集。从nested loop的输出中,整理出select中指定的字段,构造最终输出结果集。 L/? ;2vYx  
NG* CG  
1.5 进阶说明 7@xN Q 0  
J)OT71   
上面例子对inner input使用的是聚集索引,下面看一下非聚集索引的情况,加强对执行计划的理解、分析能力。 0qjS ho  
Vks3$  
把tableB col1上的主键修改为非聚集方式,示例的SQL语句执行计划如下: [2Y`0?V  
"Ul.pm\F  
[Y'Ux7.  
  
通往性能优化的JOIN方法说明(2) SaVe)+Wb~  
图2 !V~@@Rdb  
R=6i@(~G*z  
前面三个执行步骤a)、b)、c)跟1.4中一样,有一点需要注意的是,步骤c)是执行Index Seek操作,它跟Clustered Index Seek有区别。聚集索引的根节点是每一条实际数据记录,而非聚集索引的根节点是对聚集索引根结点键值的引用(如果表存在聚集索引),或者是对实际数据记录rowid的引用(指没有聚集索引的表,这种表称为heap表)。Clustered Index Seek执行之后,实际的物理数据记录已经被加载到内存中,而Index Seek操作之后,并没有加载实际的物理数据记录,而只是非聚集索引的根结点数据,其中只包含了索引字段数据以及引用的聚集索引键值或者rowid。SQL Server在这个步骤中使用非聚集索引根结点数据中的索引字段值,与outer input中的记录(rowA)关联字段进行匹配,判断是否是符合条件的结果,如果是,则将非聚集索引根结点数据结构保存到nested loop操作的输出数据结构中,并且会创建一个书签(Bookmark),指示在必要的时候需要根据这个书签去获取引用的数据。 ty?ib4=o  
QYer"o8?Gb  
d) 执行Bookmark Lookup操作。nested loop操作的输出是一个内存数据结构,在从这个内存数据结构中整理出整个查询语句的输出结果集之前,需要处理前面的书签引用问题,Bookmark Lookup操作就是根据书签中引用的聚集索引键值或者rowid获取具体记录数据。  g34zqM1  
Rp]6R Bg  
e) Filter过滤操作。回顾前面几个操作,在执行nested loop时只是使用非聚集索引的索引字段(tableB.col1)跟outer input的关联字段进行匹配,到目前为止还没有使用tableB.col2=?这个条件,这个操作就是使用tableB.col2=?对Bookmark Lookup的输出进行过滤。 Xh|Y;$Lmc  
Q:Bh*Fd9  
看的仔细的人到这里后可能会有几个疑问,1. tableA.col2=?怎么没有一个Filter操作?2. 在1.4中为什么没有出现Filter操作?解释如下:1. 在tableA上面执行的是Table Scan操作,是直接对每条实际数据进行扫描,在这个扫描过程中可以使用tableA.col2=?这个条件进行过滤,避免一个额外的Filter操作。鼠标移动到Table Scan操作上,从提示信息的参数(Argument)里面可以看到tableA.col2=?的条件已经被运用上了。2. 前面说过,聚集索引的根节点是实际数据记录,执行Clustered Index Seek的时候,最终也是扫描到了实际数据记录,在这个过程中运用tableB.col2=?这个条件,同样避免一个额外的Filter操作。这就是1.4中没有Filter操作的原因。 x|C0V~to5  
TTkww  
f) 构造返回结果集。跟1.4步骤d)一样。 A d=}Dls  
_W5[qqU  

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章