随便聊聊Oracle执行计划到底是怎么一步步来的,顺序其实没那么死板
- 问答
- 2026-01-12 03:01:30
- 1
其实很多人一提到Oracle的执行计划,脑子里可能就浮现出一个从上到下、像树杈一样分叉的图,然后觉得数据库就是严格按照这个顺序,像机器人一样一步不差地执行的,这个想法挺普遍的,但实际情况要灵活得多,甚至可以说,执行计划的“顺序感”在很大程度上是一种错觉,它更像是一个“作战方案”,而不是一个“流水线操作手册”。
要理解这个,咱们得先掰扯一下执行计划是怎么产生的,当你写好一条SQL语句,点击执行的那一刻,Oracle并不会立刻就去翻箱倒柜地找数据,它先得找个“军师”来制定作战计划,这个军师就是“查询优化器”(CBO,基于成本的优化器)。(来源:Oracle官方文档关于优化器的概念)
这个军师的工作是啥呢?它要看看你的SQL指令,我要找公司里工资最高的10个员工”,然后它就开始侦察“战场”情况:员工表有多大?有没有在工资这一列上建索引?索引的类型是啥?服务器的内存和CPU情况如何?它掌握了一大堆关于数据分布的统计信息,工资在1万到2万之间的人大概有多少”。(来源:对优化器工作方式的通用技术解读)
基于这些情报,军师会脑补出很多种不同的打法(也就是不同的执行计划)。 打法A:全表扫描员工表,把所有数据都读进来,然后在内存里排序,最后取前10名。 打法B:利用工资字段的索引,因为这个索引本身就是按工资高低排好序的,直接从索引树最右边(假设降序)开始读10条,然后再根据索引找到对应的员工详细信息。
军师会给每一种打法估算一个“成本”,这个成本不是钱,而是综合了需要消耗的CPU时间、磁盘I/O次数等资源的一个虚拟值,它选择一个它认为成本最低的打法,把这个方案画成我们看到的那个树杈图,也就是执行计划。(来源:Oracle性能优化艺术)
好了,关键来了,这个树杈图,它表示的是数据的“流动方向”和操作之间的“依赖关系”,而不是一个严格的时间顺序表。
举个例子,这个计划可能显示两个步骤:第一步是“全表扫描表A”,第二步是“通过索引访问表B”,看图的感觉好像是:先吭哧吭哧把整个表A读完,然后再去搞表B,但数据库引擎真不是这么傻干的,它很可能采用的是一种叫“嵌套循环”的连接方式。(来源:对SQL执行引擎工作原理的常见描述)
这就像是你炒一盘番茄鸡蛋,执行计划可能是:1. 处理番茄(切块),2. 处理鸡蛋(打散),3. 下锅炒,你会不会真的等所有番茄都切完,所有鸡蛋都打好,然后再开火?大概率不会吧,你可能是先点火热锅,同时另一个人在旁边打鸡蛋,你切好一个番茄就往锅里丢一个,鸡蛋打好了也立刻倒进去,这是一种“流水线”式的处理。
数据库也一样,当它从表A里扫描出第一批数据(比如几行)后,它不会傻等着把所有数据都扫描完,而是立刻把这第一批数据交给下一个步骤(比如去表B里找匹配的数据),下一个步骤一有结果,又可以立刻再往更下一个步骤传递,这样,数据就像水流一样在执行计划这个“管道”里流动起来,很多操作是并发的、交织在一起的。(来源:数据库查询执行模型的通用知识)
这就解释了为什么有时候我们看实际的执行统计信息(比如用DBMS_XPLAN.DISPLAY_CURSOR看实际执行计划),会发现某个在计划里看似在后面步骤才用到的索引,其读取次数在很早就开始增长了,因为它已经在为上游输送过来的数据提供服务了。
还有一种情况能充分说明顺序不死板,自适应执行计划”,这是Oracle 12c以后一个很聪明的功能,它承认军师(优化器)在制定计划时可能因为信息不全而判断失误。(来源:Oracle 12c自适应查询优化白皮书)
军师原本认为打法A更好,因为它预估表A和表B连接后只会产生100条数据,用嵌套循环快,但实际一运行,发现连接后产生了100万条数据,嵌套循环就慢成蜗牛了,如果是老版本,数据库只能硬着头皮把这个糟糕的计划执行完,但有了自适应能力后,数据库在运行时发现了这个巨大的估算错误,它可能会在中途“悬崖勒马”,动态地切换到另一种连接方式(比如哈希连接),这意味着,一个执行计划在运行中途,其内部结构可能已经改变了,你最初看到的那个树杈图,和实际执行的路径,可能根本不是一回事儿,这还能叫死板的顺序吗?
总结一下,我们看到的静态执行计划,是优化器在“战前”基于当时情报做出的最优猜测方案,它展示的是数据处理的逻辑依赖关系,而实际的执行过程,是一个充满动态和交互的过程,会采用流水线处理让操作重叠进行,甚至在高级功能下还会根据实际情况中途调整策略,死记硬背所谓的“执行顺序法则”是没太大意义的,更重要的是理解每个操作步骤在做什么、为什么优化器会选择它(成本估算),以及数据是如何在这些步骤之间流动的,把它理解成一个灵活的、可调整的作战地图,而不是一条单行线,更能贴近数据库引擎真实的工作方式。

本文由帖慧艳于2026-01-12发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/79064.html
