当前位置: 首页 > news >正文

Oracle学习专栏(五):性能优化

文章目录

  • 前言
  • 一、执行计划深度解析(EXPLAIN PLAN/AUTOTRACE)
    • 1.1 优化器工作流程
    • 1.2 获取执行计划的四种方法
    • 1.3 执行计划关键指标
    • 1.4 执行计划陷阱识别
  • 二、SQL调优技巧:索引策略与提示符
    • 2.1 索引策略:构建高效数据访问路径
    • 2.2 提示符(Hints):精准引导优化器
    • 2.3 索引与提示符实战案例
  • 三、等待事件分析(v$session_wait)
    • 3.1 等待事件核心概念
    • 3.2 v$session_wait 视图
    • 3.3 等待事件诊断与优化
    • 3.4 从等待事件到解决方案
  • 四、AWR报告解读
    • 4.1 核心概念和作用
    • 4.2 ADDM建议模块
    • 4.3 5步定位性能瓶颈
  • 结语


前言

性能优化是数据库管理的核心任务。本文深度解析Oracle性能优化的四大关键领域:执行计划解读SQL调优技巧等待事件分析AWR报告实施,结合代码示例与图形解析,助你精准定位瓶颈。


一、执行计划深度解析(EXPLAIN PLAN/AUTOTRACE)

执行计划是Oracle优化器生成的SQL执行路线图,它决定了SQL如何访问数据、处理连接和排序操作。理解执行计划是SQL优化的基础。

1.1 优化器工作流程

优化器工作流程
优化器基于成本模型(Cost-Based Optimizer) 选择计划,成本单位是逻辑I/O次数

1.2 获取执行计划的四种方法

  1. EXPLAIN PLAN(静态计划):EXPLAIN PLAN是Oracle提供的静态分析SQL执行路径的方法,它通过生成逻辑执行计划帮助预测SQL性能表现,而无需实际执行SQL语句‌。
-- 生成执行计划
EXPLAIN PLAN FOR
SELECT e.last_name, d.department_name 
FROM employees e 
JOIN departments d ON e.department_id = d.department_id
WHERE e.salary > 10000;-- 显示计划
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
  1. AUTOTRACE(SQLPlus专用):AUTOTRACE是SQLPlus提供的自动跟踪功能,可显示SQL执行计划和统计信息‌。

SQL*Plus 是 Oracle 公司提供的交互式命令行工具,用于与 Oracle 数据库进行交互和管理。作为 Oracle 数据库的标准接口工具,它允许用户执行 SQL 语句、PL/SQL 块以及管理数据库对象。

‌配置步骤‌:
1.运行utlxplan.sql脚本创建PLAN_TABLE。
2.运行plustrce.sql脚本创建角色plustrace。
3.将角色plustrace授予用户。

SET AUTOTRACE TRACEONLY EXPLAIN;  -- 仅显示计划
SET AUTOTRACE ON;                -- 显示结果+计划
  1. 实时执行计划(v$sql_plan)
-- 先执行SQL
SELECT /*+ MONITOR */ * FROM employees WHERE department_id = 60;-- 查询计划
SELECT * 
FROM v$sql_plan 
WHERE sql_id = (SELECT sql_id FROM v$sql WHERE sql_text LIKE '%MONITOR%');
  1. SQL Monitor(11g+ 图形化监控):Oracle SQL Monitor 是 Oracle 数据库企业版提供的实时 SQL 监控工具,用于动态捕获和分析正在执行的 SQL 语句的性能特征和执行计划‌。
SELECT DBMS_SQL_MONITOR.REPORT_SQL_MONITOR(sql_id => 'g8ruhm9sxz3tk',type => 'TEXT'
) AS report 
FROM dual;

1.3 执行计划关键指标

基础指标定义与解读:

  • Operation‌:操作类型,描述数据库执行的具体操作,如TABLE ACCESS FULL(全表扫描)、INDEX RANGE SCAN(索引范围扫描)等‌。
  • Rows(Cardinality)‌:优化器估算的当前操作返回的行数,基于统计信息计算得出‌。
  • Bytes‌:执行该步骤后返回的字节数,反映操作处理的数据量‌。
  • Cost‌:优化器估算的执行成本,包含CPU和I/O开销,理论上越小越好‌。
  • Time‌:Oracle估计的当前操作所需时间‌。
  • TempSpc‌:预估操作使用临时表空间的大小,用于排序、哈希连接等内存密集型操作‌。

指标间数学关系:
执行计划中各关键指标存在紧密的关联关系:

  • Cost计算‌:Cost = I/O cost + CPU cost,其中%CPU表示CPU成本占总Cost的百分比‌。
  • Cardinality估算‌:基数=表行数×选择率,选择率计算准确性直接影响执行计划质量‌。
  • Bytes与Rows关系‌:Bytes ≈ Rows × 平均行长度,反映数据吞吐量‌。

1.4 执行计划陷阱识别

  1. 统计信息失真
-- 检查估算行数 vs 实际行数
SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM orders WHERE status = 'SHIPPED';-- 对比报告
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'ALLSTATS LAST'));

DBMS_XPLAN.DISPLAY_CURSOR 是 Oracle 数据库提供的关键性能诊断工具,用于显示库缓存中SQL语句的实际执行计划‌,与预估执行计划工具不同,它直接从共享池获取已执行SQL的真实运行时信息。

当A-Rows(实际行数)与E-Rows(估算行数)差异>10倍时,需更新统计信息:

EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT','ORDERS');
  1. 隐式类型转换
-- 执行计划显示
filter(TO_NUMBER("PHONE")=123456)  -- 索引失效!

解决方案:

ALTER TABLE customers MODIFY phone VARCHAR2(20);  -- 统一类型

使用DBMS_XPLAN.DISPLAY_CURSOR获取实际执行计划比EXPLAIN PLAN更准确,因为它包含运行时信息。定期使用DBMS_STATS收集统计信息是保持执行计划稳定的基础。

二、SQL调优技巧:索引策略与提示符

2.1 索引策略:构建高效数据访问路径

  1. 索引类型与适用场景
索引类型适用场景创建示例注意事项
B-Tree索引高选择性列(主键、唯一键)CREATE INDEX idx_emp_id ON emp(emp_id);默认索引类型
位图索引低基数列(性别、状态码)CREATE BITMAP INDEX idx_gender ON emp(gender);仅适用于OLAP系统
函数索引列参与函数运算的查询CREATE INDEX idx_upper_name ON emp(UPPER(last_name));维护成本高
复合索引多列组合查询CREATE INDEX idx_dept_job ON emp(dept_id, job_id);遵循最左前缀原则
反向键索引缓解索引热点块(如序列主键)CREATE INDEX idx_emp_id_rev ON emp(emp_id) REVERSE;范围查询失效
  1. 索引设计原则
    • 选择性原则:索引选择性 = 不同值数量 / 总行数。
      建议:选择性 > 0.1 的列才适合建索引。
    • 最左前缀原则(复合索引)。
    • 避免冗余索引。
  2. 索引失效的七大陷阱与解决方案
失效场景示例解决方案执行计划表现
隐式类型转换WHERE emp_id = ‘100’ (数字列)统一类型:WHERE emp_id = 100TABLE ACCESS FULL
索引列参与运算WHERE salary*1.1 > 5000改写:WHERE salary > 5000/1.1FILTER 操作
前导通配符查询WHERE name LIKE ‘%SON%’使用反向函数索引TABLE ACCESS FULL
NOT 或 <>WHERE status <> ‘ACTIVE’改用 OR 或位图索引FULL SCAN
IS NULL 判断WHERE commission IS NULL创建函数索引:NVL(commission,0)TABLE ACCESS FULL
OR 条件未覆盖WHERE dept=10 OR job=‘MANAGER’创建复合索引或UNION ALLCONCATENATION
统计信息过时索引存在但未使用更新统计信息成本估算偏差大

2.2 提示符(Hints):精准引导优化器

Oracle Hint是嵌入在SQL注释中的特殊指令,用于向优化器提供执行计划的指导建议,格式为/*+ hint */或–+ hint。它不是强制命令,优化器会根据实际情况决定是否采纳‌。

  1. 提示符语法规范
SELECT /*+ HINT_NAME(参数) */ ...  -- 必须紧接SELECT后
FROM table_name;

关键规则:

  • Hint必须放在/*+ … */注释中,+号必须紧跟在/*后面。
  • 多个Hint可以组合使用,用空格分隔。
  • Hint对大小写不敏感,必须紧跟在SELECT/UPDATE/DELETE等关键字后‌。
  1. 核心提示符分类解析

访问路径提示符:

提示符作用使用场景示例
INDEX(table idx)强制使用特定索引优化器选择了低效索引SELECT /*+ INDEX(emp idx_emp_dept) */ …
FULL(table)强制全表扫描小表或需要全扫描的特殊场景SELECT /*+ FULL(emp) */ …
INDEX_FFS(table idx)快速全索引扫描仅需索引列且数据量大SELECT /*+ INDEX_FFS(emp idx_emp) */ …

连接方式提示符:

-- 嵌套循环连接(小表驱动)
SELECT /*+ USE_NL(orders customers) */ *
FROM orders JOIN customers USING(customer_id);-- 哈希连接(大数据集等值连接)
SELECT /*+ USE_HASH(emp dept) */ *
FROM emp JOIN dept ON emp.dept_id = dept.dept_id;-- 排序合并连接(有序数据集)
SELECT /*+ USE_MERGE(orders order_items) */ *
FROM orders JOIN order_items USING(order_id);

连接顺序提示符:

-- 强制连接顺序:dept → emp → jobs
SELECT /*+ LEADING(dept emp jobs) */ dept.dname, emp.ename, jobs.job_title
FROM dept
JOIN emp ON dept.dept_id = emp.dept_id
JOIN jobs ON emp.job_id = jobs.job_id;

并行执行提示符:

-- 指定并行度4
SELECT /*+ PARALLEL(emp 4) */ * FROM emp;-- 禁止并行
SELECT /*+ NO_PARALLEL(emp) */ * FROM emp;

2.3 索引与提示符实战案例

案例1:复合索引优化分页查询
问题SQL:

SELECT * FROM (SELECT /*+ INDEX_FFS(orders)*/ orders.*, ROWNUM rn FROM orders WHERE customer_id = 100 ORDER BY order_date DESC
) WHERE rn BETWEEN 101 AND 120;

优化步骤:

  • 创建复合索引:
CREATE INDEX idx_cust_orders ON orders(customer_id, order_date DESC);
  • 添加提示符:
SELECT /*+ INDEX(orders idx_cust_orders) */ ...

案例2:函数索引优化日期查询
低效查询:

SELECT * FROM sales 
WHERE TRUNC(sale_date) = DATE '2023-01-01';  -- 索引失效

优化方案:

  • 创建函数索引:
CREATE INDEX idx_trunc_saledate ON sales(TRUNC(sale_date));
  • 使用提示符:
SELECT /*+ INDEX(sales idx_trunc_saledate) */ *
FROM sales
WHERE TRUNC(sale_date) = DATE '2023-01-01';

调优策略:
调优策略

三、等待事件分析(v$session_wait)

3.1 等待事件核心概念

Oracle等待事件(Wait Event)是数据库系统中关键的性能指标,用于描述会话在执行SQL语句过程中等待某些资源或条件的时间。当会话无法立即获得所需资源时,Oracle会将其置于等待状态,并记录:等待类型(事件名称),等待时长,等待资源标识,阻塞者信息。
等待事件本质
等待事件分类:

类别占比典型事件优化方向
User I/O40%db file sequential readSQL优化/缓存/存储
Concurrency25%enq: TX - row lock contention事务设计/锁优化
Configuration15%latch: shared pool内存调整/游标共享
Commit10%log file sync提交频率/日志写入优化
Network5%SQL*Net message to client网络延迟/应用设计
Idle5%SQL*Net message from client通常忽略

3.2 v$session_wait 视图

关键字段解析:

SELECT sid, event, wait_time, seconds_in_wait, state,p1, p2, p3,  -- 事件特定参数blocking_session,blocking_session_status
FROM v$session_wait 
WHERE wait_class != 'Idle';  -- 过滤空闲事件
  • event:等待事件名称(诊断核心)
  • state:
    • WAITING:当前正在等待
    • WAITED UNKNOWN TIME:历史等待(无计时)
    • WAITED SHORT TIME/WAITED KNOWN TIME:历史等待(有时长)
  • wait_time:
    • 0:当前正在等待
    • | 0:上一次等待时间(厘秒)
  • seconds_in_wait:当前等待已持续秒数(对state=WAITING有意义)
  • p1, p2, p3:事件参数(需结合v$event_name解读)
  • blocking_session:阻塞会话的SID(锁争用关键)

v$session_wait是Oracle数据库中关键的性能诊断视图,用于实时监控会话的等待事件情况。它记录了每个会话当前正在等待或最近完成的等待事件详细信息,是Oracle性能调优的重要工具‌

3.3 等待事件诊断与优化

  1. db file sequential read(单块读)

本质:索引访问/表通过ROWID访问时单块I/O。
优化方案:
优化方案
具体措施
检查热点段:SELECT * FROM v$segment_statistics WHERE statistic_name=‘physical reads’;
优化SQL减少逻辑读:索引优化、避免回表。

  1. enq: TX - row lock contention(行锁竞争)

诊断

-- 查找锁持有者
SELECT sid, sql_id, blocking_session
FROM v$session 
WHERE blocking_session IS NOT NULL;

解决方案
应用层:缩短事务时间,及时提交
数据库层:SELECT … FOR UPDATE NOWAIT。

该语句的主要功能是在查询数据时立即尝试获取行级排他锁,如果目标行已被其他事务锁定,则立即返回错误(ORA-00054)而不等待锁释放‌

紧急处理:ALTER SYSTEM KILL SESSION ‘sid,serial#’;

ALTER SYSTEM KILL SESSION命令用于终止Oracle数据库中的指定会话,其完整语法格式为:
ALTER SYSTEM KILL SESSION ‘sid,serial#’ [IMMEDIATE];
参数说明:
sid:会话标识符,可通过查询V$SESSION视图获取‌。
serial#:会话序列号,用于唯一标识会话实例‌。
IMMEDIATE:可选参数,指定后会话将立即终止而不等待事务完成‌。

  1. log file sync(日志同步)

优化
组提交(COMMIT_WRITE参数)
异步提交:COMMIT WRITE BATCH NOWAIT;
优化日志写入:使用高速磁盘/调整日志文件大小

  1. latch: shared pool(共享池闩锁)

触发原因:硬解析过多
排查

SELECT * FROM v$sqlarea WHERE parse_calls > 1000; -- 高解析SQL

解决
绑定变量:ALTER SYSTEM SET cursor_sharing=‘FORCE’;(谨慎使用)
刷新共享池:ALTER SYSTEM FLUSH SHARED_POOL;(应急)

3.4 从等待事件到解决方案

案例:订单提交卡顿
现象:

  • 用户反馈提交订单时响应慢
  • 监控发现log file sync等待激增

诊断步骤:

  1. 定位相关会话:
SELECT sid, program, sql_id 
FROM v$session 
WHERE event = 'log file sync';
  1. 分析SQL:
SELECT sql_text FROM v$sql WHERE sql_id = 'g8ruhm9sxz3tk';
-- 发现为INSERT订单明细
  1. 检查事务模式:
-- 应用代码检查:每次插入明细后立即提交
  1. 优化方案:
    批量提交:每100条明细提交一次。
    使用异步提交:COMMIT WRITE BATCH NOWAIT;

四、AWR报告解读

4.1 核心概念和作用

核心概念:
AWR(Automatic Workload Repository):Oracle内置的性能仓库,每60分钟自动采集一次系统快照(包括SQL执行统计、等待事件、资源消耗等),默认保留8天。
AWR报告:基于两个快照生成的性能分析报告,提供负载概况、等待事件、SQL性能、资源瓶颈等全景视图。

作用:
定位性能瓶颈:识别CPU、I/O、内存或SQL层面的问题根源。
建立性能基线:通过历史快照对比,量化优化效果。
减少人工诊断时间:自动化采集数据,避免手工抓取性能指标。

核心模块解读(附关键指标):
下表为AWR报告中需重点关注的模块及指标:

模块关键指标健康阈值异常影响
负载概况(Load Profile)Redo size/s, Logical reads/s, Hard parses/s<100次/秒高硬解析导致CPU争用
实例效率(Instance Efficiency)Buffer Hit %, Library Hit %, Soft Parse %>95%低命中率引发I/O暴增
Top 10等待事件DB CPU,db file sequential read,log file syncDB CPU排名前高I/O等待暴露存储性能不足
SQL统计(SQL Statistics)SQL ordered by Elapsed Time SQL ordered by Gets无固定阈值单条SQL拖垮整个实例

深度解析要点:

  1. 等待事件分析

若log file sync等待过高 → 事务提交频繁,需优化提交方式(如批量提交)。
db file scattered read(多块读)持续高位 → 全表扫描泛滥,检查缺失索引。

  1. SQL性能分析

关注Elapsed Time排名前5的SQL:

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('sql_id')); -- 提取执行计划:cite[7]

高Gets(逻辑读)SQL:可能缺少索引或存在低效连接。

4.2 ADDM建议模块

ADDM(Automatic Database Diagnostic Monitor):基于AWR快照的智能诊断引擎,自动分析性能问题并给出优化建议。
核心功能:检测CPU瓶颈、锁争用、I/O问题、SQL负载等,并推荐硬件调整、参数优化、SQL重构等方案。

重要作用
主动预防:在问题影响业务前提前预警(如预测undo表空间不足)。
跨维度关联:将等待事件、SQL性能、资源配置关联分析。

怎么用?
步骤1:生成ADDM报告

@?/rdbms/admin/addmrpt.sql  -- 输入起止快照ID:cite[5]:cite[9]

步骤2:解读建议优先级
ADDM报告按影响程度排序建议,优先处理高收益(Benefit) 且低成本(Cost) 项,例如:

  • ✅ 高优先级:通过索引减少全表扫描(预估节省30% DB Time)
  • ⚠️ 低优先级:升级CPU(需硬件投资,节省15% DB Time)

步骤3:执行优化动作

  • SQL优化示例:
-- 使用SQL Tuning Advisor
DECLAREtask_name VARCHAR2(30);
BEGINtask_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_id => 'abc123');DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name);DBMS_OUTPUT.PUT_LINE(DBMS_SQLTUNE.REPORT_TUNING_TASK(task_name)); 
END;

输出建议可能包括:创建索引、重构SQL、接受统计信息。

  • 参数调整示例:
    若建议增大PGA_AGGREGATE_TARGET:
ALTER SYSTEM SET pga_aggregate_target=8G SCOPE=SPFILE;

步骤4:验证优化效果
比较优化前后的AWR报告关键指标:

  • Elapsed Time下降幅度
  • 等待事件减少比例(如db file sequential read降低50%)

4.3 5步定位性能瓶颈

  1. 选择有效快照范围
    问题时段优先(如10:00–11:00 AM),避免包含空闲时间:
SELECT snap_id, begin_time FROM dba_hist_snapshot 
WHERE begin_time > SYSDATE - 1/24; -- 最近1小时快照
  1. 分析负载趋势:检查DB Time vs Elapsed Time
    • 若DB Time ≫ Elapsed Time → 系统过载。
    • 若DB Time << Elapsed Time → 系统空闲或存在外部阻塞。
  2. Top等待事件诊断
    • DB CPU排名第一 → CPU瓶颈(需检查Top SQL by CPU)。
    • enq: TX - row lock contention → 应用事务逻辑缺陷(如未提交事务)。
  3. SQL性能聚焦:联合分析以下两类SQL
    • SQL ordered by Elapsed Time:优化长耗时SQL。
    • SQL ordered by Executions:高频SQL即使单次快,总量也可能消耗大资源。
  4. 内存与I/O瓶颈
    • Buffer Hit % < 90% → 需扩大DB_CACHE_SIZE。
    • Avg Physical Read Time > 20ms → 存储性能不足(升级SSD或调整HBA队列)。

构建性能优化闭环


结语

性能优化是持续过程:

  1. 监控:通过AWR/v$session_wait捕获问题
  2. 分析:解读执行计划定位瓶颈
  3. 解决:索引优化、SQL重构、参数调整
  4. 验证:对比优化前后性能指标

行动指南: 每周生成AWR报告,每日检查关键等待事件,对TOP SQL持续优化!


文章转载自:
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://.
http://www.dtcms.com/a/280067.html

相关文章:

  • 适用于Windows系统截图工具
  • 通用综合文字识别联动 MES 系统:OCR 是数据流通的核心
  • 【算法-BFS 解决最短路问题】探索BFS在图论中的应用:最短路径问题的高效解法
  • JVM——JVM垃圾回收调优的主要目的是什么?
  • 行为模式-状态模式
  • C++ -- STL-- List
  • 分布式通信框架 - JGroups
  • 从零开始的云计算生活——第三十二天,四面楚歌,HAProxy负载均衡
  • 数据怎么分层?从ODS、DW、ADS三大层一一拆解!
  • 智慧园区:激活城市活力的数字化引擎
  • 【colab 使用uv创建一个新的python版本运行】
  • mac上的app如何自动分类
  • 22-C#的委托简单使用-2
  • 自增主键为什么不是连续的?
  • 基于多智能体强化学习的医疗检索增强生成系统研究—MMOA-RAG架构设计与实现
  • Uboot源码超详细分析(2)
  • 力扣25.7.15每日一题——有效单词
  • 对于编写PID过程中的问题
  • TCP可靠性设计的核心机制与底层逻辑
  • TDengine GREATEST 和 LEAST 函数用户手册
  • 26.将 Python 列表拆分为多个小块
  • SSM框架学习DI入门——day2
  • 跨平台移动开发技术深度分析:uni-app、React Native与Flutter的迁移成本、性能、场景与前景
  • IOS 18下openURL 失效问题
  • Flutter瀑布流布局深度实践:打造高性能动态图片墙
  • LVS(Linux Virtual Server)详细笔记(理论篇)
  • JavaScript进阶篇——第三章 箭头函数核心
  • 【问题排查流程总结】tmd2635模块开发中断异常,排查心得
  • python技巧:使用pyvisa控制仪器;安装NI-VISA等visa库;导入pyvisa并创建资源管理器;打开和使用仪器
  • 【 Cache 写策略学习笔记】