当前位置: 代码迷 >> 综合 >> Oracle 管理优化器的统计信息之系统统计信息 System Statistics
  详细解决方案

Oracle 管理优化器的统计信息之系统统计信息 System Statistics

热度:25   发布时间:2024-01-16 02:22:19.0
系统统计信息主要描述的是系统的硬件性能,如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
  相关解决方案