应优先过滤executions低但buffer gets异常高的sql,如executions=1且buffer gets>500000,大概率是大表全表扫描或未走索引;再检查rows processed/buffer gets比值,若远低于10–20,表明访问路径低效。

别把“SQL ordered by Gets”当性能问题清单——高逻辑读不等于慢,它只说明SQL访问了大量缓存块,可能是高效缓存命中,也可能是低效全表扫描。关键得结合Rows Processed、Elapsed Time和执行计划交叉判断。
怎么看“SQL ordered by Gets”才不误判
AWR报告里这一节列出的是单位时间内累计buffer gets最高的SQL,但它反映的是“内存访问强度”,不是“响应时间”。比如一条高频小查询(如查用户配置)可能buffer gets上百万,但单次elapsed time才1ms,对用户体验毫无影响。
- 优先过滤
Executions低但Buffer Gets异常高的SQL:比如Executions = 1、Buffer Gets > 500000,大概率是大表扫描或未走索引 - 对比
Rows Processed和Buffer Gets比值:若比值 TABLE ACCESS FULL扫千万行只取几条 - 跳过
Buffer Gets高但CPU Time和Elapsed Time都极低的SQL——它们只是“勤快”,不是“慢”
如何定位真正有问题的高Gets SQL
光看排序列表不够,得往下翻到对应SQL的执行计划(Plan Hash Value部分),并确认是否真有性能隐患:
- 找
Operation列含TABLE ACCESS FULL或INDEX FAST FULL SCAN的语句,尤其当Rows列显示实际返回行数远小于表总行数时 - 检查
Predicate Information(需用DBMS_XPLAN.DISPLAY_AWR带ADVANCED格式查,TYPICAL默认不显示):是否有谓词未下推、函数包裹字段(如TO_CHAR(col))、隐式类型转换导致索引失效 - 对比同一
sql_id在不同快照中的plan_hash_value:若buffer gets突增但plan_hash_value变了,说明执行计划劣化,不是SQL本身问题
为什么不能只盯着Gets排序页做优化
这个页面容易引导你优化“错的问题”:
-
SQL ordered by Gets里的高值SQL,可能是OLAP类报表查询,本来就需要扫大量数据——优化方向是分区裁剪、物化视图,不是加索引 - 某些SQL
buffer gets高,但physical reads几乎为0,说明全在Buffer Cache里完成,I/O压力为零;而另一条buffer gets中等但physical reads超10万的SQL,才是真正IO瓶颈 - RAC环境下,
buffer gets包含跨实例的global cache gets,高值可能反映的是Cache Fusion争用,而非SQL写法问题
实操建议:三步快速筛出该动的SQL
别从头读完整个AWR报告。直接用以下逻辑缩小范围:
- 先查
SQL ordered by Disk Reads:单条physical reads > 100000必须处理,这是真实I/O压力源 - 再回看
SQL ordered by Elapsed Time:找Elapsed Time/Executions > 1000ms的SQL,这是用户感知到的“卡” - 最后交叉比对:在上述两组SQL中,挑出同时出现在
SQL ordered by Gets前20的——这些才是“又慢、又吃资源、又高频”的真瓶颈
真正难的不是找到高Gets SQL,而是判断它值不值得优化:扫100行表的SELECT *和扫1000万行的SELECT *,优化价值差两个数量级。别省略Rows Processed和表大小验证这一步。











