欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Oracle数据库性能优化

程序员文章站 2022-06-02 12:57:30
...

Oracle数据库性能优化

一.数据库性能优化

Oracle 性能管理既是一种艺术,也是一种科学。从实用角度讲,它可以分 为两种类型,主动式和被动式性能管理。主动式性能管理涉及到特定系统实施初 期的设计和开发,包括硬件选择、性能及容量规划,海量存储系统的选择, I-O 子系统配置及优化,以及如何对不同组件进行定制,以满足 Oracle 数据库和应 用系统的复杂要求。
被动式性能管理涉及到现有环境中不同组件的性能评估、故障排除和 Oracle 环境的优化。本文旨在探讨如何进行被动式性能调优,以便为 Oracle 性能调优 提供必要的指导,从而避免仅仅通过反复尝试的方式进行性能调优,提高 Oracle 性能管理的效率。
所以 ORACLE 数据库性能恶化表现基本上都是用户响应时间比较长,须要用 户长时间的等待。获得满意的用户响应时间有两个途径:
一是减少系统服务时间,即提高数据库的吞吐量; 二是减少用户等待时间,即减少用户访问同一数据库资源的冲突率。 对于以上的两个问题,通常我们采用以下几个方面来进行改善:
 调整服务器内存分配。例如,可以根据数据库运行状况调整数据库系统 全局区(SGA 区)的数据缓冲区、日志缓冲区和共享池的大小;还可以 调整程序全局区(PGA 区)的大小。
 调整硬盘 I/O 问题,达到 I/O 负载均衡。
 调整运用程序结构设计
 优化调整操作系统参数和使用资源管理器
SQL 优化、诊断 latch 竞争、Rollback(undo) Segment 优化、提升 block
的效率等等

二.检查Oracle数据库性能

检查 Oracle 数据库性能情况,包含:检查数据库的等待事件,检查死锁及 处理,检查 cpu、I/O、内存性能,查看是否有僵死进程,检查行链接/迁移,定 期做统计分析,检查缓冲区命中率,检查共享池命中率,检查排序区,检查日志缓冲区,总共十个部分。

2.1 检查数据库的等待事件

select sid,event,p1,p2,p3,WAIT_TIME,SECONDS_IN_WAIT from v$session_wait where event not like 'SQL%' and event not like  'rdbms%';

如果数据库长时间持续出现大量像 latch free,enqueue,buffer busy waits, db file sequential read,db file scattered read 等等待事件时,需要对其 进行分析,可能存在问题的语句。

2.2 Disk Read最高的SQL语句的获取

SELECT SQL_TEXT FROM (SELECT * FROM V$SQLAREA ORDER BY DISK_READS) WHERE ROWNUM<=5 desc;

2.3 查找前十条性能差的sql

SELECT * FROM (SELECT PARSING_USER_ID EXECUTIONS,SORTS,COMMAND_TYPE,DISK_READS, SQL_TEXT FROM V$SQLAREA ORDER BY DISK_READS DESC) WHERE ROWNUM<10 ;

2.4 等待时间最多的 5 个系统等待事件的获取

SELECT * FROM (SELECT * FROM V$SYSTEM_EVENT WHERE EVENT NOT LIKE 'SQL%' ORDER BY TOTAL_WAITS DESC) WHERE ROWNUM<=5;

2.5 检查运行很久的SQL

COLUMN USERNAME FORMAT A12 COLUMN OPNAME FORMAT A16 COLUMN PROGRESS FORMAT A8
SELECT	USERNAME,SID,OPNAME,ROUND(SOFAR*100	/	TOTALWORK,0)		||	'%'	AS PROGRESS,TIME_REMAINING,SQL_TEXT	FROM	V$SESSION_LONGOPS	,	V$SQL		WHERE
TIME_REMAINING <> 0 AND SQL_ADDRESS=ADDRESS AND SQL_HASH_VALUE = HASH_VALUE;

2.6 检查消耗CPU最高的进程

SET LINE 240 SET VERIFY OFF
COLUMN SID FORMAT 999 COLUMN PID FORMAT 999 COLUMN S_# FORMAT 999
COLUMN USERNAME FORMAT A9 HEADING "ORA USER"
COLUMN PROGRAM FORMAT A29 COLUMN SQL	FORMAT A60
COLUMN OSNAME FORMAT A9 HEADING "OS USER"
SELECT P.PID PID,S.SID SID,P.SPID SPID,S.USERNAME USERNAME,S.OSUSER OSNAME,P.SERIAL# S_#,P.TERMINAL,P.PROGRAM PROGRAM,P.BACKGROUND,S.STATUS,RTRIM(SUBSTR(A.SQL_TEXT, 1, 80)) SQLFROM V$PROCESS P, V$SESSION S,V$SQLAREA A WHERE P.ADDR = S.PADDR AND S.SQL_ADDRESS = A.ADDRESS(+) AND P.SPID LIKE '%&1%';

2.7 检查碎片程度高的表

SELECT segment_name table_name,COUNT(*) extents FROM dba_segments WHERE owner NOT IN ('SYS', 'SYSTEM') GROUP BY segment_name HAVING COUNT(*)=(SELECT  MAX(COUNT(*))
FROM dba_segments GROUP BY segment_name);

2.8 检查表空间的 I/O 比例

SELECT DF.TABLESPACE_NAME NAME,DF.FILE_NAME "FILE",F.PHYRDS PYR, F.PHYBLKRD PBR,F.PHYWRTS PYW, F.PHYBLKWRT PBW FROM V$FILESTAT F, DBA_DATA_FILES DF WHERE F.FILE# = DF.FILE_ID ORDER BY DF.TABLESPACE_NAME;

2.9 检查文件系统的 I/O 比例

SELECT SUBSTR(A.FILE#,1,2) "#", SUBSTR(A.NAME,1,30) "NAME", 
A.STATUS,A.BYTES,B.PHYRDS,B.PHYWRTS  FROM  V$DATAFILE  A,  V$FILESTAT  B  WHERE A.FILE# =
B.FILE#;

2.10 检查死锁及处理

select sid,serial#,username,SCHEMANAME,osuser,MACHINE, terminal,PROGRAM,owner,object_name,object_type,o.object_id from dba_objects o,v$locked_object l,v$session  s
where o.object_id=l.object_id and s.sid=l.session_id;

oracle 级 kill 掉该 session

alter system kill session  '&sid,&serial#';

操作系统级 kill 掉 session

#>kill -9 pid

2.11 检查数据库cpu、I/O、内存性能

记录数据库的 cpu 使用、IO、内存等使用情况,使用 vmstat,iostat,sar,top
等命令进行信息收集并检查这些信息,判断资源使用情况。

CPU 使用情况:
[[email protected] ~]# top

系统 I/O 情况:
iostat -k 1 3
系统负载情况:
#uptime

2.12 查看是否有僵死进程

有些僵尸进程有阻塞其他业务的正常运行,定期杀掉僵尸进程。

select spid  from v$process where addr not in (select paddr from  v$session);

2.13 检查行链接/迁移

Sql>select table_name,num_rows,chain_cnt From dba_tables Where owner='CTAIS2' And chain_cnt<>0;

2.14 检查缓冲区命中率

SELECT a.VALUE + b.VALUE logical_reads, c.VALUE phys_reads,
round(100*(1-c.value/(a.value+b.value)),4) hit_ratio FROM v$sysstat a,v$sysstat b,v$sysstat c
WHERE a.NAME='db block gets' AND b.NAME='consistent gets' AND c.NAME='physical reads' ;

2.15 检查共享池命中率

select sum(pinhits)/sum(pins)*100   from v$librarycache;

2.16 检查排序区

select name,value from v$sysstat where name like '%sort%';

如 果 disk/(memoty+row) 的 比 例 过 高 , 则 需 要 调 整
sort_area_size(workarea_size_policy=false 或
pga_aggregate_target(workarea_size_policy=true)

2.17 检查日志缓冲区

select name,value from v$sysstat where name in ('redo entries','redo buffer allocation retries');

三 性能调优及方法

性能调优主要有主动调优和被动调优,主动调优在前面我们已经进行了阐述, 被动调优主要有以下方法进行。

  • 确定合理的性能优化目标

  • 测试并记录当前的性能指标

  • 确定当前存在的 Oracle 性能瓶颈 (Oracle 中何处存在等待,哪个 SQL语句与此有关)

  • 确定当前的操作系统瓶颈

  • 优化相关的组件 (应用、数据库、I/O、连接 OS 及其它)

  • 跟踪并实施变化管理制度

  • 测试并记录目前的性能指标

  • 重复第 3 到第 7 步直至达到既定的优化目标 不要对并非性能瓶颈的部分进行优化,否则可能引起额外的问题。

正如任何聪明的人会告诉你的:“如果还未坏,千万不要修”。更重要的是,一旦既定的优 化目标已经达到,就务必停止所有的优化。
获取 Oracle 的性能指标 (测试前及测试后)必须在峰值处理时测试并获取系 统在优化前和优化后的性能指标。数据采集不应在数据库 instance 刚刚起动后 进行。 同时, 测试 数据 应在峰 值期 间每过 15 分 钟进 行一次 。初 始化参数

TIMED_STATISTICS 应该被设为 TRUE。
通过运行以下脚本开始快照:

$ORACLE_HOME/rdbms/admin/utlbstat.sql.

通过运行以下脚本结束快照:

$ORACLE_HOME/rdbms/admin/utlestat.sql.

完成 utlestat.sql 操作后,会在当前目录中生成名为“report.txt”的文件, 包含系统的性能数据。该报告包括每 15 分钟捕获的所有与 Oracle 例程相关的 参数。

3.1. 寻找问题根源

如上所述,通过查看 v s y s t e m e v e n t 事 件 开 始 系 统 事 件 的 问 题 诊 断 。 下 一 步 是 查 看 v system_event 事件开始系统事件的问题诊断。下一 步是查看 v systemeventvsession_event,找出引起或经历等待事件的进程。最后一步是通过 v$session_wait 获得事件的细节。同时,应该进一步通过 OS 进行深入分析,了 解核心的 CPU、内存和 IO 状态参数。最后,结合两种不同的诊断的结论,找出 系统瓶颈所在。

3.2 System_Event事件

v$system_event 可以从全局的角度查看 Oracle 系统中的所有事件。尽管它 并不包括任何进程级的信息(当前或历史),但却可以显示上次例程弹出后总的等 待时间。这种动态性能视图中的数据,会在下次例程起动时清零。出于这种原因, 这种视力中的数据应该在不同时段进行抽样。

3.3Session_Event事件

v s e s s i o n e v e n t 视 图 在 进 程 级 提 供 与 v session_event 视图在进程级提供与 v sessioneventvsystem_event 相同的信息(即, SID 等)。这种视图可以从“system-wide events” 级进一步钻取,到达进程级, 以确哪个进程引起或经历了等待事件。

3.4Session_Wait

v$session_wait 视图在特定事件的进程级提供低层次的信息挖掘。不同于 其它一些视图,这种方式可以“实时”获取进程级的等待信息。这是真正有用的 信息。切记,每次查看这一视图得到的结果可能不一样。这可能与数据库中当前 的活动有关。

3.5 应用优化

从统计(和现实) 的角度看,80% 的 Oracle 系统性能问题可以通过 SQL 代码 优化来解决。任何应用优化的过程,不外乎是索引优化、全表扫描、并行机制改 进和选择正确数据组合方法的过程。这正是要达到最佳应用性能所必须考虑的因 素。没有 SQL 的优化,就无法实现高性能的应用。良好的 SQL 语句可以减少 CPU 资源的消耗,提高响应速度。同时,优化后的 SQL 语句还可以提高应用的可扩 展性,这是除增加大量内存外,任何其它硬件手段也无法实现的。

四 例程调优

需要配置的主要初始化参数 以下是一些已知与例程优化关系最密切的一些核心 Oracle 初始化参数。它
们都会影响 Oracle 及 SGA 区的活动。任何对这些参数的改动,在实施到生产环 境之前,都必须进行测试。一旦改变了生产环境的参数,就必须对相关的 Oracle 动态性能指标和操作系统的性能进行监测,寻找可能由此产生的异常现象。

1. DB_BLOCK_SIZE

该参数在数据库建立前设定,决定了数据库中每个数据块的大小。只有重新 建立数据库,才有可能改变该参数。db_block_size 的配置应遵循以下公式: DB_BLOCK_SIZE = FILESYSTEM BLOCKSIZE >= O-S PAGESIZE 这可以确保 Oracle
获得最佳 I/O 性能,同时不会由于冗余或不必要的 I/O,给 I/O 子系统带来压力。

2. DB_BLOCK_BUFFERS

该参数决定了 SGA 区数据库缓冲区中的块数量。由于这是 Oracle 读取和写入的区域,它的不正确配置会引起严重的 I/O 性能问题。尽管缓冲区的大小与应 用性质、数据库大小、同步用户数等无关,它的确是 SGA 区中最大的组件。经常 可以看到缓冲区占用 75-80%SGA 区内存的情况。另外,这一参数设置过大,也会 引起整个系统的内存不足,引起操作系统过多的读写操作。
该参数及 SHARED_POOL_SIZE 通常是两个最重要的 SGA 优化目标。只有当数 据库缓冲率长时间低于 70%时,才需要增加其大小说。即使在这种情况下,也需 要进一步审查应用的性能和整个系统的吞吐性。若存在延迟性的应用设计问题, 则无论数据库缓冲区的大小如何,缓冲和读写率都不会有太大改变为。在实调优 中,也曾发现由于 SQL 语句的问题,出现缓冲率很高,但仍存在全系统性能问题 的情况。

3. SHARED_POOL_SIZE

该参数按字节数设定,定义了 SGA *享区的大小。该组件的大小严重依赖 于应用的类型 (即该应用是重用 SQL,还是生成动态 SQL,等等)。同时它也取决 于同步用户的数量,以及实例是否被配置成支持多线程服务器(MTS)。如果该应 用采用了 MTS 配置,则共享区应该明显增加,因为光标状态和用户进程数据等程 序全局区域(PGA)都被置入了共享区。
有关多数应用的 SHARED_POOL_SIZE 大小设置,可以从每 10 个同步用户 16 MB 共享区开始。这不是一成不变的,因为应用的性质最终会决定该组件的大小。只 有当库缓冲和字典缓冲使用率一直低于 90%时,才需要关注这一参数。但如果应 用并未采用变量合并和/共离图标时,内存的数量并不会使缓冲使用率高于 90%。
共享区过大会导致处理时间增加,甚至 SQL 语句的挂起。如果应用不能有效 地重用 SQL,则无论配置多大的库缓冲或字典缓冲都无济于事,不能改善缓冲使 用率。
另一个值得考虑的因素是需要随时使用的存储 PL/SQL 代码数量。应用的核 心包可以通过查看 DBA_SOURCE 、 USER_SOURCE 得以确认,其大小通过查询 DBA_OBJECT_SIZE 了解。另外,为了确定存储 PL/SQL 是否被置于内存,可以查 询动态性能视图 V$DB_OBJECT_SIZE。内时,包 DBMS_SHARED_POOL 中的程序大小 可被用于确定应用中大包的规模。

4. LOG_BUFFER

根据字节设定,该参数定义了 SGA 缓冲区中 redo log 的大小。缺省值通常 是数据库块大小的四倍,这对于多数环境并不是最佳的。对于中型的 Oracle 环 境,其结构应该为 512 Kb 左右。对该存储结构而言,更大并不意味着更好。超 过 1 MB 就可能有问题。需要监控 V$SESSION_WAIT 中 log buffer space 的等待 事件,以优化该内存结构。需要提醒的是,在线 redo log 文件的大小设置不当, 会引起 redo 请求的等待。

5. DB_WRITERS

该参数可以针对所有文件系统支持,且不可使用 Direct I-O 的 Oracle 实施 设定。这并不需要与 raw partitions 一起使用,因为异步 I-O 更加。建议将该 参数设定为(2 * 独立磁盘驱动器数量/卷)。该参数只有在 report.txt 中的 “average write queue length”持续高于 1 时,才需要设定。在 Oracle 8.0 和 更高版本中,该参数已不再被支持,而为其它两个名为 DB_WRITER_PROCESSES 和 DBWR_IO_SLAVES 的参数取代。若需要设置 DB_WRITER_PROCESSES 值高于 8,则 DB_WRITER_PROCESSES 可被设为 1,且 DBWR_IO_SLAVES 可被设为 “n”,其中 n 的值必须设置为 (2 * 独立磁盘驱动器数量/卷)

五 其他优化

5.1 I-O 优化

I-O 优化是系统优化中的一个关键步骤,还涉及到其它任务,将文件在不同 驱动器/卷中进行分布,采用优化分区技术、确定 I-O 子系统瓶颈、确定控制器 瓶颈并根据应用的类型选择最佳的 RAID 级。I-O 优化应该在全面了解 Oracle 及 Oracle RDBMS 结构之后进行。应该在进行 I-O 优化前后实施 I-O 数据监控,如 平均服务时间,IOPS,平均磁盘队列长度等。

5.2 竞争优化

多数与 Oracle 有关的竞争问题可以通过主动配置管理相关的初始化参数进 行。不恰当地配置 init.ora 中的锁参数可能引起竞争。为了不打破其中的平衡, 所需的参数可进行配置并主动得以处理。
包括表在内的 数据库对 象可能存在 两个竞争 点。第一个 是所配置的 “freelists”的数量 (缺省值为 1)。freelist 结构维护着表中可用于插入的 块。对于存在大量同步插入的表,有必要配置该结构。为了以主动方式处理 freelist 竞争,必须在建立表时配置 FREELISTS。可考虑的最佳值为 (2 * CPU 数量) 。V$WAITSTAT 不可能指示存在 freelist 竞争,除非存在 freelist 组, 而这种设置只存在于 Oracle Parallel Server 中。即便如此,也无法了解哪个 表存在竞争中。主动式的 freelist 竞争 调优可以事先预防问题出现。
资源竞争的第二个来源与索引有关,即对象块头中配置的事务槽数量。事务 槽是块头中的区域,是事务处理进程采用自身识别号进行注册,以便任何被修改 的更能够通过特定事务槽数量在低层得以识别的地方。如果所有现存的事务槽已 经被其它事务占用,服务器器进程会从块的 PCTFREE 中请求 23 个字节,建立一 个新的槽。这种情况适用于存在大量同步事务的对象。对于事务槽的竞争,需要 设置 INITRANS 参数。对于块大小为 8K 的数据库,多数情况下,4 为最佳设置, 占用的空间仅为 92 字节,却可以大大减少运行时故障和性能问题。

5.3 O-S 监控

数据库忙时,应该对操作系统进行监控,因为操作系统的性能指标会揭示数 据库活动的性质及其对系统的影响。例如,为了了解 CPU 的利用率,可以通过 system activity reporter (sar – u interval frequency) 、 mpstat (Sun Solaris), top (多数 UNIX)、 osview (SGI Irix) 及 vmstat 等命令。Sar 和 vmstat 也可被用于确定包括内存使用率、I-O 参数、队列等待、读取/交换区活 动等信息。在 Solaris 上,mpstat utility 也可用于获取前面提到的 CPU 利用 率数据。Solaris 上的 Adrian 性能管理工具也很有用。可以利用其中的一到多 个工具来确定系统的性能状况,找出可能存在的瓶颈。
Oracle 数据库性能的管理需要遵循系统的方法论,以确保所有核心问题得 以解决。多数问题可以事先得以管理。了解与 O-S 相关的问题是成功的关键。勿 需置疑,系统硬件配置上的良好平衡也是至关重要的。必须承认, 80% 的系统 性能问题可以通过书写更好的 SQL 语句来解决。来文试图探究其余 20%中可能覆 盖的内容。同时,必须遵守严格的规定,在调优目标达到后终止所有努力。了解 自己想到何处是重要的,更重要的是,要知道自己何时到达了目的地。