系统统计信息主要描述的是系统的硬件性能,如cpu、io性能和使用。查询优化器基于这些信息选择执行计划。系统统计信息让优化器更加精确的评估cpu和io的cost。
工作量模式:Oracle收集并分析一段时间内系统的活动情况,形成数据,基于的是真实的工作量。
非工作量模式:模拟一个工作量产生数据,如随机向各个数据文件发出读请求,然后统计相关信息。
使用包DBMS_STATS.GATHER_SYSTEM_STATS来收集系统统计信息,建议收集系统统计信息,新收集的系统统计信息不会使已经解析的sql语句变无效。新的sql语句解析会基于新得系统统计信息。当存在工作量模式下的系统统计信息时,非工作量模式下的系统统计信息会被忽略。
下图是主要的系统统计信息指标解释:
1.工作量模式
工作量模式下的系统统计信息包括:
(1).单块读时间(sreadtim)
(2).多块读时间(mreadtim )
(3).多块读平均块数(mbrc)
(4).I/O最大吞吐(maxthr)
(5).并行从属I/O进程的平均吞吐(slavethr)
(6).cpu速度(cpuspeed)
Oracle计算sreadtim,mreadtim,mbrc的方法是在2个时间点之间,统计随机单块物理读和连续多块物理读次数。Oracle计数的标准是物理读的数据读到了buffer cache中。
因为计数是在buffer cache中,因此也就会存在I/O延迟、latch争用和任务切换等。工作量模式下的统计信息基于这段统计时间窗口系统的活动情况。如果这段时间I/O遇到了瓶颈,那么统计数据就会反应出这个情况,
并且推荐需要更少I/O的执行计划。这种情况下的系统统计信息收集不会给系统带来负担。
收集工作量统计信息
开始收集
DBMS_STATS.GATHER_SYSTEM_STATS('start')
停止收集
DBMS_STATS.GATHER_SYSTEM_STATS('stop')
指定时间窗口长度收集并自动停止,n代表多少分钟
DBMS_STATS.GATHER_SYSTEM_STATS('interval', interval=>N)
删除并重置到非工作量模式的系统统计信息
dbms_stats.delete_system_stats()
多块读平均块数(mbrc)
在工作量模式下,Oracle会统计mbrc,用来估算全表扫描的成本。然而,假如在统计的时间段内,没有全表扫描发生,这在oltp系统经常发生。即使是在DSS环境,全表扫描可能使用并行,绕过buffer cache。这种情况下,系统依然会收集sreadtim因为存在索引查找使用buffer cache。
如果Oracle不能统计到mbrc或者mreadtim,但是统计到了sreadtim和cpuspeed,那么它只会使用sreadtim和cpuspeed来计算成本。对于全表扫描来说,它会使用初始化参数DB_FILE_MULTIBLOCK_READ_COUNT来估算,如果DB_FILE_MULTIBLOCK_READ_COUNT被设置为0,优化器会使用DB_FILE_MULTIBLOCK_READ_COUNT=8来计算成本。
2.非工作量模式
非工作量模式下的系统统计信息包括:
(1).I/O转移时间是1次读请求可以读取的数据量的比率,单位(Bytes/ms)(iotfrspeed)
(2).I/O搜索时间=搜索时间+延迟时间+系统时间开销(ioseektim)
(3).非工作量模式下的CPU速度(cpuspeednw)
非工作量模式下的系统统计信息收集和工作量模式下不同,随机向各个数据文件发出读请求,然后统计相关信息。
ioseektim代表搜索到磁盘头的时间。一般从5 ms to 15 ms不等。iotfrspeed代表I/O速度,从每秒几兆到几百兆不等。
Oracle一般保守设置iotfrspeed。
Oracle默认使用非工作量模式的系统统计信息和cpu成本模型,非工作量模式的系统统计信息在实例第一次启动初始化为以下值:
ioseektim = 10ms
iotrfspeed = 4096 bytes/ms,约为4m/秒
cpuspeednw = 收集的值,随系统不同而不同
收集非工作量统计信息
--手动收集,不带参数,一般需要几秒到几分钟不等,不要在系统繁忙时收集
DBMS_STATS.GATHER_SYSTEM_STATS()
--手动设置相关参数值
DBMS_STATS.SET_SYSTEM_STATS