【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执行计划稳定如一

相关推荐
java_logo1 分钟前
Docker 部署 FalkorDB:轻松搭建属性图数据库与知识图谱平台
数据库·docker·知识图谱·falkordb·轩辕镜像·falkordb部署教程·falkordb部署文档
小白说大模型24 分钟前
Spring AI 框架中集成 MCP 的完整指南:从服务端到客户端的全流程实践
大数据·数据库·人工智能·安全·spring·chatgpt·开源
计算机魔术师39 分钟前
第二届世界人形机器人运动会开幕:2056 台机器人齐聚“冰丝带“,666 支队伍竞技 51 赛项
数据库·人工智能·机器人
@insist12341 分钟前
系统集成项目管理工程师-配置管理角色与活动
数据库·软考·系统集成项目管理工程师·软考中项·软件水平考试
巨大八爪鱼1 小时前
XP系统运行IoTDB 2.0.10数据库服务器
数据库·iotdb·xp
卓怡学长1 小时前
w181springboot机场乘客服务系统
java·数据库·spring boot·spring·intellij-idea
阮胜昌2 小时前
MySQL 9.7.0 LTS 现已发布:扩展了社区功能,并为企业级应用增加了动态数据脱敏功能
数据库·mysql
晓子文集2 小时前
Tushare接口文档:每日涨跌停价格(stk_limit)
大数据·数据库·金融数据·量化投资
微学AI2 小时前
我把 800 行报错日志压成一张排障卡:用蓝耘元生代做 FastAPI 日志根因分析
网络·oracle·fastapi