【Oracle】Oracle诊断系列(5/6):统计信息与执行计划——优化器的“大脑”管理

Oracle诊断系列(5/6):统计信息与执行计划------优化器的"大脑"管理

🔗 接上一篇《Oracle表空间与对象管理》,今天我们深入数据库的"大脑"------优化器 ,解决执行计划不稳定和统计信息过期问题。 你是否遇到过: - 同一个SQL,昨天快今天慢? - 执行计划突然变差? - 索引明明存在却不使用? 这些问题,很可能是因为统计信息问题。今天,我就带你掌握统计信息的管理和执行计划的分析。


🧠 优化器工作原理 Oracle优化器流程:

SQL → 语法分析 → 语义分析 → 生成执行计划 → 执行

关键依赖

  • 统计信息:表行数、列分布、索引唯一性等
  • 系统参数optimizer_mode
  • 硬件信息:CPU、I/O性能

⚠️核心原则

没有完美的执行计划,只有最适合当前数据分布的计划


1️⃣ 统计信息状态检查

✅ 表统计信息

sql 复制代码
-- 检查表统计信息是否过期 
SELECT table_name, num_rows, last_analyzed, ROUND((SYSDATE - last_analyzed), 2) AS days_since_analyzed FROM user_tables WHERE table_name = 'YOUR_TABLE'; 

🚨 警报

  • last_analyzed 超过7天 → 建议重新收集
  • num_rows 与实际差异大 → 统计信息不准
✅ 索引统计信息
sql 复制代码
-- 索引统计信息 
SELECT index_name, num_rows, distinct_keys, blevel, leaf_blocks, last_analyzed FROM user_indexes WHERE table_name = 'YOUR_TABLE';

解读

  • blevel:B树层级,越大扫描成本越高
  • distinct_keys:唯一键数,影响选择性

2️⃣ 执行计划分析

✅ 查看当前执行计划
sql 复制代码
-- 查看正在运行的SQL执行计划 
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id', NULL, 'ALLSTATS LAST')); 
✅ 查看历史执行计划
sql 复制代码
-- 从AWR中查看历史计划 
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('sql_id')); 

关键字段

  • A-Rows:实际返回行数
  • E-Rows:预估返回行数
  • A-Time:实际执行时间
  • Buffers:逻辑读
    🔍 关注点
  • A-Rows vs E-Rows 差异 > 10倍 → 统计信息不准 > - 全表扫描 vs 索引扫描 → 选择性判断

3️⃣ 统计信息收集

✅ 手动收集表统计信息
sql 复制代码
-- 收集单表统计信息 
BEGIN DBMS_STATS.GATHER_TABLE_STATS( ownname => 'SCHEMA_NAME', tabname => 'TABLE_NAME', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO', degree => 4, cascade => TRUE ); END; / 

参数说明

  • estimate_percent:采样率,AUTO_SAMPLE_SIZE 自动选择

  • method_opt:直方图收集策略

  • cascade:同时收集索引统计信息

✅ 锁定统计信息(防自动收集)
sql 复制代码
-- 锁定表统计信息 
EXEC DBMS_STATS.LOCK_TABLE_STATS('SCHEMA_NAME', 'TABLE_NAME'); 
-- 解锁 
EXEC DBMS_STATS.UNLOCK_TABLE_STATS('SCHEMA_NAME', 'TABLE_NAME'); 

💡 使用场景

  • 测试环境 > - 特殊表(如维表)不需要频繁收集

4️⃣ 执行计划稳定性

✅ SQL Profile(推荐)

sql 复制代码
 -- 为SQL创建SQL Profile(需 Tuning Pack 许可) 
 DECLARE my_sqlprofile_name VARCHAR2(30); 
 BEGIN 
my_sqlprofile_name := DBMS_SQLTUNE.ACCEPT_SQL_PROFILE ( task_name => 'tuning_task_1', name => 'my_profile'); 
 END; / 
✅ SQL Plan Baseline
sql 复制代码
-- 加载SQL到Baseline 
BEGIN 
DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE( sql_id => 'abc123def456'); 
END; / 

优势

  • 不需要额外许可 > - 可管理多个执行计划

✅ 统计信息管理最佳实践

场景 建议
新表 首次加载后立即收集
大表 业务低峰期收集
频繁DML 每日收集或使用增量统计
维表 锁定统计信息
执行计划突变 检查统计信息和绑定变量

📣 总结 统计信息管理三步法:

  1. 🕵️‍♂️ 检查统计信息是否过期
  2. 🔍 分析执行计划的预估 vs 实际
  3. 🛠️ 及时收集或锁定统计信息

🔗 下期预告 : > 最后一篇《Oracle经典案例实战 》,我们将整合所有知识,进行一轮演示。

📌 点赞 + 收藏,掌握优化器核心!
👉 让你的SQL执行计划稳定如一

相关推荐
2401_871696522 小时前
JavaScript中代码覆盖率Coverage在精简脚本中的应用
jvm·数据库·python
NineData2 小时前
NineData将亮相2026德国汉诺威工业博览会
运维·数据库·后端
m0_734949792 小时前
Python GUI界面如何实现主题美化_引入ttk模块实现原生外观风格
jvm·数据库·python
m0_678485452 小时前
如何让导航栏的下落动画效果更慢?
jvm·数据库·python
qq_432703662 小时前
Pandas DataFrame 分组聚合中处理 JSON 列的高效方法
jvm·数据库·python
qq_424098562 小时前
MySQL高负载下查询中断怎么解决_增加系统内存与调整参数
jvm·数据库·python
2301_773553622 小时前
SQL中如何处理多维数据的查询:复合索引与SELECT编写
jvm·数据库·python
大江东去浪淘尽千古风流人物2 小时前
【cuVSLAM】项目解析:一套偏工程实战的 GPU 紧耦合视觉惯性 SLAM
数据库·人工智能·python·机器学习·oracle
解救女汉子2 小时前
Layui表格如何使用第三方插件实现树形展示
jvm·数据库·python