AWR报告中Buffer Gets排名需查看「SQL Statistics」部分的「Buffer Gets」列降序结果,而非Executions或Elapsed Time;默认仅显示前30条,需用awrrpt.sql加-topn参数扩展;注意区分「SQL ordered by Gets」(逻辑读)与「SQL ordered by Reads」(物理读)。
AWR报告里Buffer Gets排名怎么看
直接看awr报告的「sql statistics」部分,找「buffer gets」列从高到低排序的sql。注意不是「executions」或「elapsed time」——buffer gets反映的是逻辑读总量,和单次执行的buffer gets per exec是两回事。默认报告只显示前30条,如果想看更多,得用awrrpt.sql脚本加-topn参数重跑,比如@?/rdbms/admin/awrrpt.sql后输topn=100。
常见错误:把「SQL ordered by Gets」和「SQL ordered by Reads」混淆——后者是物理读,和磁盘IO相关,不解决逻辑读高问题。
怎么定位这些高Buffer Gets SQL是否在扫大表
拿到SQL ID后,查dba_hist_sql_plan(或v$sql_plan),重点看operation字段是否含TABLE ACCESS FULL,再结合object_name和object_owner确认是不是大表。别只看表名,要查真实大小:select bytes/1024/1024 as mb from dba_segments where segment_name = 'XXX' and owner = 'YYY'。
容易踩的坑:
- 忽略分区表:
TABLE ACCESS FULL可能只扫一个分区,但报告里仍算全表名,得核对partition_start/partition_stop - 物化视图或视图展开:SQL文本里没出现大表名,但执行计划里有,必须看实际
object_name - 绑定变量导致
sql_text被截断:优先以sql_id关联dba_hist_sql_plan,别只依赖SQL文本搜索
DBA_HIST_SQLSTAT里buffer_gets_delta和executions_delta怎么配对看
这两个值来自同一快照区间,但要注意:如果SQL在该区间内没被刷新进v$sql(比如刚解析完就失效),buffer_gets_delta可能为0,而历史数据里却有值——所以必须限定dbid、instance_number、sql_id、snap_id四者完全匹配,再做差值计算。
性能影响点:
-
buffer_gets_delta是累计值,不是瞬时速率,不能直接除以时间算QPS - 如果
executions_delta = 0但buffer_gets_delta > 0,说明SQL没“执行完”(比如硬解析失败、被cancel),这时候逻辑读是无效消耗 - Oracle 12c+开始,
io_cell_offload_eligible_bytes等新字段会影响buffer_gets统计口径,老脚本若没过滤con_id可能跨PDB混算
关联查询中谁在拖慢逻辑读——怎么看Predicate Information
执行计划末尾的Predicate Information段落才是关键。它告诉你哪些条件没走索引、哪些被推到了最外层、哪些filter操作在全表扫描后才生效。比如看到filter("T2"."STATUS"='ACTIVE')出现在NESTED LOOPS外层,而T2又是百万级表,基本就能断定这是瓶颈。
实操建议:
- 用
dbms_xplan.display_awr(sql_id, plan_hash_value)带format=>'ALL'参数,确保看到完整Predicate Information - 对比
access和filter:前者走索引定位,后者是扫描后过滤,filter越多越危险 - 注意
dynamic sampling提示:如果计划里有dynamic sampling used for this statement,说明统计信息过期,buffer_gets高可能是优化器误判导致
真正难的不是找到高逻辑读SQL,而是判断那个filter是不是真能加索引,或者要不要改写连接顺序——这得看业务语义,工具给不了答案。










