Oracle性能分析11:系统统计信息

早期Oracle查询优化器的开销计算是基于执行SQL语句所需要的物理读,这个方法被叫做I/O开销模式(I/O cost model),这个方法的主要缺点是认为单块读和多块读开销相当。在Oracle 8i中,初始化参数optimizer_index_caching和optimizer_index_cost_adj解决了这个问题,但参数的默认值仅适用于报告系统和数据仓库。直到Oracle 9i,ORacle引入了一种新的CPU开销模式(CPU cost model),消除了这个缺陷,但必须提供数据库引擎所在的系统的性能信息,即系统统计信息。这篇文章将介绍系统统计信息和收集系统统计信息的方法。

系统统计信息

系统统计信息放在表aux_stats$中,可以通过下面的方法查看该视图中的数据(需要DBA用户或者有该表的查看权限):

select * from aux_stats$;

SNAME			PNAME		PVAL1				PVAL2
---------------------------------------------------------------------
SYSSTATS_INFO	STATUS							COMPLETED
SYSSTATS_INFO	DSTART							08-30-2005 15:04
SYSSTATS_INFO	DSTOP							08-30-2005 15:04
SYSSTATS_INFO	FLAGS		1
SYSSTATS_MAIN	CPUSPEEDNW	484.974958263773
SYSSTATS_MAIN	IOSEEKTIM	10
SYSSTATS_MAIN	IOTFRSPEED	4096
SYSSTATS_MAIN	SREADTIM
SYSSTATS_MAIN	MREADTIM
SYSSTATS_MAIN	CPUSPEED
SYSSTATS_MAIN	MBRC
SYSSTATS_MAIN	MAXTHR
SYSSTATS_MAIN	SLAVETHR

表中的数据包括3个部分,使用SNAME区分:

1)SYSSTATS_INFO表示系统统计信息状态和时间
STATUS在正确收集时为COMPLETED;如果出现问题,显示为BADSTATS,在这种情况下查询优化器将不使用统计信息;该字段还可以为:MANUALGATHERING和AUTOGATHERING。

2)SYSSTATS_MAIN表示系统统计信息结果集
该部分的信息分为非工作量统计信息(noworkload statistics)和工作量统计信息(workload statistics),两者的主要差别是度量I/O子系统性能的方法有所不同,后面具体讨论。
非工作量统计在Oracle 10g之后总是提供,包括:

CPUSPEEDNW	一个CPU一秒钟能处理的操作数,单位百万次/秒
IOSEEKTIM	平均磁盘寻道时间,单位毫秒,默认10
IOTFRSPEED	平均每毫秒从磁盘传输的字节数,默认为4096

工作量统计信息必须显示地收集后才可用,包括:

SREADTIM	单块数据平均读取时间,单位毫秒
MREADTIM	多块数据平均读取时间,单位毫秒
CPUSPEED	一个CPU一秒钟能处理的操作数,单位百万次/秒
MBRC		一次多块读操作的平均读取数据块数
MAXTHR		整个系统的最大I/O吞吐量(字节/秒)
SLAVETHR	并行处理中从属线程的平均I/O吞吐量(字节/秒)

3)SYSSTATS_TEMP用来计算系统统计信息,只有收集工作量统计信息时才可用

收集系统统计信息

使用工具包dbms_stats中的存储过程gather_system_stats收集系统统计信息,可以收集非工作量统计信息或者工作量统计信息。

非工作量统计信息

从Oracle 10g开始,总是提供默认的非工作量统计信息,如果显式地删除,下次数据库启动时会自动收集。收集非工作量统计信息要在空闲的系统上进行,使用那个下面的语句:

begin
  dbms_stats.gather_system_stats(gathering_mode => 'noworkload');
end;

收集非工作量统计信息只需要很短的时间,但有时需要重复收集多次才能生效。

工作量统计信息

收集工作量统计信息,不能使用空闲的系统,以为数据库引擎要利用正常的数据库负载来评估I/O子系统的性能。
工作量统计信息的收集包含下面的步骤:

1)执行快照并存储各种性能指标的初始值到数据字典表aux_stats$(列SNAME设定为SYSSTATS_TEMP)。使用下面的方式来启动:

begin
  dbms_stats.gather_system_stats(gathering_mode => 'start');
end;

2)等待足够的时间产生一个有代表性的负载时候再进行另一次快照,等待时间通常不少于30分钟;

3)进行第二次快照,使用下面的语句:

begin
  dbms_stats.gather_system_stats(gathering_mode => 'stop');
end;

4)Oracle根据两次快照之间的差值,计算出系统统计信息,如果无法计算的话,将被设置为空。

你也可以指定gathering_mode为interval,并指定间隔时间来收集工作量统计时间,这样就不用手工停止快照,下面的命令指定30分钟后进行第二次快照:

begin
  dbms_stats.gather_system_stats(gathering_mode => 'interval',
                                 interval       => 30);
end;

需要注意上面的语句并不会延续30分钟,它只是启动一个作业调度后返回。
使用工作量统计信息需要尽量避免收集到没有代表性的工作量信息,可以收集多天的工作量统计信息,然后将mbrc、mreadtim、sreadtim和cpuspeed指标取平均值,maxthr和slavethr取最大值,再使用delete_system_stats过程删除旧的系统统计信息,然后使用set_system_stats设定新的系统统计信息,存储过程如下:

begin
  dbms_stats.delete_system_stats();
  dbms_stats.set_system_stats(pname => 'CPUSPEED', pvalue => 772);
  dbms_stats.set_system_stats(pname => 'SREADTIM', pvalue => 5.5);
  dbms_stats.set_system_stats(pname => 'MREADTIM', pvalue => 19.4);
  dbms_stats.set_system_stats(pname => 'MBRC', pvalue => 53);
  dbms_stats.set_system_stats(pname => 'MAXTHR', pvalue => 1136136192);
  dbms_stats.set_system_stats(pname => 'SLAVETHR', pvalue => 16870400);
end;

 

你可能感兴趣的:(oracle)