暂无图片
暂无图片
6
暂无图片
暂无图片
暂无图片

Oracle:看懂执行计划顺序

原创 淘气 2026-01-26
351

分析执行计划是解决ORACLE慢SQL的重要手段。获取到ORACLE的执行计划后,经验丰富的DBA根据连接方式、访问路径等可能一眼就能看出性能问题在哪里;但新手DBA可能不清楚执行计划该从哪里看,也不清楚执行计划的顺序是什么。所以这篇文章想尽可能的说清楚怎么看ORACLE执行计划顺序。

Table of Contents

1.执行计划样例

这里有一个执行计划样例,下文所有的讲解都是基于如下执行计划进行的。可以先看一下,先尝试自己进行排序。首先说明的是Id列数字并不是执行计划的顺序号。

1.执行计划.png

2.基础知识了解

2.1.父子兄弟节点

Oracle的执行计划是树形结构,执行顺序类似于二叉树。理解执行计划中的父节点、子节点、兄节点、弟节点是至关重要的。

2.1.1.父子节点

2.父子节点.png

可以根据执行计划缩进来判断父子节点。如上图所示,可以看到一条红色箭头,下面用Id号来代替Operation步骤。

1 比 0 缩进一格,且 0 在上方;则 1 是 0 的子节点,0 是 1 的父节点。

2 比 1 缩进一格,且 1 在上方;则 2 是 1 的子节点,1 是 2 的父节点。

以此类推…

10 比 9 缩进一格,且 9 在上方;则 10 是 9 的子节点,9 是 10 的父节点。

10 比 11 缩进一格,且 11 在下方,10 在上方,则 10 与 11 无父子关系。

也可以说 10 与 11 无任何关系,唯一的关系就是在同一个树形结构上。

2.1.2.兄弟节点

3.兄弟节点.png

同样,可以根据执行计划的缩进来判断兄弟节点。如上图所示,可以看到4条红色箭头,下面用Id号来代替Operation步骤。

9 与 11 缩进相同,9在上,11在下;则9是兄节点,11是弟节点。

8 与 12 缩进相同,8在上,12在下;则8是兄节点,12是弟节点。

7 与 13 缩进相同,7在上,13在下;则7是兄节点,13是弟节点。

6 与 15 缩进相同,6在上,15在下;则6是兄节点,15是弟节点。

新手可能会有疑问:为什么上文中的 14 与 8、12缩进相同,但却不是兄弟节点呢?

这是因为13在14上方,14比13缩进一格,所以14是13的子节点,与8、12没有兄弟关系。

2.2.深度

这里的深度就是上文提到的缩进,代表着执行计划某一个步骤的深度

例如上文描述的 Id 为5的步骤,相比与 Id 为0的步骤有5个缩进,其深度就是5;这也代表着此步骤有5层父步骤(Id为4、3、2、1、0)。

可以通过下面的SQL查看执行计划步骤的深度值。其中id是执行计划中的Id号,parent_id是其父节点的Id号,depth就是深度值。

select sp.id sp.parent_id, sp.depth, sp.operation|| '' || sp.options as operation, sp.object_name from v$sql_plan sp where sp.sql_id = 'xxxx'

2.3.position

position代表拥有相同父节点的兄弟节点执行顺序。

在树形结构中,树中每个级别最左的叶节点最先执行。结合起来理解是在树形结构中左为兄、右为弟,在执行计划列表中上为兄、下为弟。

可以用下面的SQL查询执行计划的position。

select sp.id sp.parent_id, sp.depth, sp.postion, sp.operation|| '' || sp.options as operation, sp.object_name from v$sql_plan sp where sp.sql_id = 'xxxx'

SQL输出结果如下图。可以发现Id为9和Id为11的步骤拥有相同的父节点8,且深度相同;其中Id为9的position值是1,Id为11的position值是2,这表示Id为9的步骤先于Id为11的步骤执行。

4.position.png

这体现在树形结构中,Id为9的步骤是左节点,Id为11的步骤是右节点;体现在执行计划列表中则是Id为9的步骤在上,Id为11的步骤在下(这一点大家在前文中的执行计划列表截图中可以看得出)。

3.树形结构转换

前文讲了很多次树形结构,但新手可能对此并不了解,脑海中无法形成概念。我自己早些时候也是查了很多资料去理解数据结构中的树,所以在这里和大家分享将执行计划转换成树形结构去加深理解。

执行计划转换成树形结构过程拆解。

(1)拆解步骤1

前文已知执行计划每个步骤的深度,其中最深的是Id=10的步骤(这也是执行计划的入口)。

前文已知 10 的父节点是9,9的弟节点是11,左为兄、右为弟。

前文已知9与11的父节点是8。

所以,此时树形图如下:

5.树形1.png

(2)拆解步骤2

8与12是兄弟节点,8为兄、12为弟,左为兄、右为弟。

8与12的父节点是7。

所以,此时树形图如下:

6.树形2.png

(3)拆解步骤3

7与13是兄弟节点,7为兄、13为弟,左为兄、右为弟。

7与13的父节点是6。

所以,此时树形图如下所示:

7.树形3.png

(4)拆解步骤4

6与15是兄弟节点,6为兄、15为弟,左为兄、右为弟。

6与15的父节点是5。

13是14的父节点。

所以,此时树形图如下所示:

8.树形4.png

(5)拆解步骤5

Id为0、1、2、3、4依次为后一位的父节点,0是根节点。

所以最终的树形结构如下所示:

9.树形5.png

(6)树形结构总结

到第(5)步,这个执行计划的完整树形结构已经呈现出来了。这里再总结下根据树形结构如何查看执行顺序,也就是数据结构中的树形顺序。

① 从顶部开始

② 在树形结构中向左下移动,直至达到左节点(再也没有子节点的左节点);首先执行此节点。

10.树形6.png

③ 查看此节点(首先执行的节点)有无同级节点,也就是弟节点;有则执行弟节点。

9有其同级弟节点11,所以执行11。

④ 执行完这两个节点,再向上执行它们的父节点。

执行完11后,9与11的父节点是8,所以执行8。

此时执行顺序是 10->9->11->8

⑤ 完成这一组父子节点后,在树形结构中,向上退一级,查看上退后这一组的父子节点,先左子节点,再右子节点,最后父节点。

按照前文描述规律依次执行。

需要注意的是14优先于13执行,因为14是13的子节点。如果某节点有子节点,则先执行子节点;如果有两个同级子节点,则先执行左子节点。

此时的执行顺序是 10->9->11->8->12->7->14->13->6

⑥ 在树形结构中依照此逻辑不断上移,直至根节点。

最终的执行顺序是 10->9->11->8->12->7->14->13->6->15->5->4->3->2->1->0

4.实战技巧

在工作中进行SQL优化时,分析执行计划肯定不可能像前文一样查父节点、深度、position,然后再画个树形结构图。没有这么多时间,客户也没耐心等。前文的描述都只是为了加深理解。

在工作中应该怎么快速理清楚执行计划顺序呢?

分享一种我经常用的方法。

(1)利用截图工具的箭头找到执行计划入口

11.实战1.png

(2)看入口步骤有没有弟节点,再看弟节点有没有子节点

如果有弟节点,弟节点无子节点,那么第二步就是该弟节点。

如果有弟节点,弟节点有子节点,那么第二步就是从该弟节点开始用第Ⅰ步中箭头方式,找到它的没有子节点的节点。

像我们这个执行计划,入口没有弟节点。那么,就往上找它的父节点,即9,第二步执行9。

(3)拉长箭头找对应的兄弟节点

找到执行计划的入口后,没有弟节点,就往上走(上为父)。根据前文描述:先弟节点,弟节点执行完了,执行父节点。

且执行计划用肉眼直接去看兄弟节点,很容易看错的。所以可以借助截图工具中的箭头拉长,看两个步骤是否有相同的缩进。比对后相同缩进的步骤就是兄弟节点,上为兄,下为弟;兄先于弟执行

对于这个例子而言,执行完9,通过箭头发现,11是它的弟节点,所以下一步执行11。

执行完11,执行9和11的父节点8,执行完8,通过箭头发现12是8的弟节点,所以下一步执行12。

以此类推,就可以得出执行顺序了。

10->9->11->8->12->7->14->13->6->15->5->4->3->2->1->0

12.实战2.png

这种方法适合刚开始接触执行计划的新手DBA使用,如果经常看执行计划,这种方法很快也可以抛弃了,因为肉眼就可以大致判断出执行计划顺序了。

最后修改时间:2026-01-26 09:50:17
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论