在Oracle执行计划中,
E-Rows
和
A-Rows
是评估SQL性能的两个核心指标,它们分别代表了优化器的“预估值”和SQL运行时的“实际值”
。
在实际使用中,
E-Rows
和
A-Rows
的关系并非简单的
A-Rows = E-Rows * Starts
,主要存在两种情况:
分区操作
:当SQL涉及分区表时,
PARTITION RANGE ALL
或
PARTITION HASH ALL
等操作会按分区执行。由于每个分区的数据特征可能不同,优化器可能为每个分区单独估算
E-Rows
,但在执行计划的顶层,
A-Rows
显示的是所有分区的总和,而
E-Rows
显示的可能是某个分区的估算值或总和,导致两者关系复杂
。
并行查询
:在并行执行中,多个并行进程会同时处理数据,各自产生
A-Rows
。此时,
E-Rows
是优化器对整个操作的总估算,而
A-Rows
可能是所有并行进程产生行数的总和,或是某个协调进程接收到的行数,这使得直接对比变得困难
。
因此,在排查分区或并行相关的SQL性能问题时,不能简单套用公式,需要结合具体的执行计划和数据分布来解读。
获取包含这些详细信息的执行计划,主要有两种方法:
方法一:使用Hint (推荐)
这是最常用的方法。在SQL语句中加入
/*+ GATHER_PLAN_STATISTICS */
提示,然后执行SQL。之后,通过
DBMS_XPLAN.DISPLAY_CURSOR
函数查看执行计划:
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
方法二:修改会话设置
在执行SQL前,设置当前会话的统计级别:
alter session set statistics_level = all;
对比
E-Rows
和
A-Rows
是发现SQL性能问题的关键。当两者出现数量级上的巨大差异时,就意味着优化器的基数估计出现了严重偏差
。这通常会导致优化器选择低效的执行计划,例如:
低估 (E-Rows << A-Rows) :优化器认为只返回少量数据,可能错误地选择了 嵌套循环连接(Nested Loops) 。然而,当实际数据量远大于预期时,嵌套循环的代价会呈指数级增长,导致性能急剧下降 。
高估 (E-Rows >> A-Rows) :优化器错误地认为会返回海量数据,可能选择了不必要的 全表扫描(Full Table Scan) 或 哈希连接(Hash Join) ,导致额外的I/O和内存开销 。
类似地,还有A-Time
A-Time
(实际累计耗时) 会
累加所有子操作的耗时
。这意味着,一个父操作的耗时必然大于或等于其任何一个子操作的耗时。因此,不能仅凭某个操作
A-Time
值最大,就断定它是瓶颈,因为它的时间可能完全花费在它的子操作上。定位瓶颈需要“由下至上”地观察,找到那些自身消耗了显著时间,而其子操作耗时较小的操作
。
当发现
E-Rows
与
A-Rows
差异巨大时,要查看统计信息是否准确,特别是直方图。
根据排查结果,可以采取以下优化手段:
E-Rows
和
A-Rows
是评估优化器质量、定位SQL性能瓶颈的“照妖镜”。通过分析它们的差异,可以找到优化器“误判”的根本原因,并采取针对性的优化措施,如更新统计信息、创建直方图或调整SQL写法。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/7655508/viewspace-3117567/ ,如需转载,请注明出处,否则将追究法律责任。