系统统计信息(System Statistics)

系统统计信息(system statistics)为查询优化器(query optimizer)描述了系统的硬件特征,如I/O和CPU

的性能与利用率。当选择执行计划(execution plan)时,优化器会为每个查询估计I/O和CPU资源。系统统

计信息使得查询优化器可以更准确地估计I/O和CPU的花费(cost),从而使得查询优化器选择一个更好的执

行计划。

 

当Oracle收集系统统计信息时,它会在一个特定的时间段里分析系统活动(工作量统计信息(workload

statistics)),或者模拟一个工作量(非工作量统计信息(noworkload statistics))。这些统计信息是

使用DBMS_STATS.GATHER_SYSTEM_STATS来收集的。Oracle公司强烈建议你收集系统统计信息。

 

你必须拥有DBA权限或GATHER_SYSTEM_STATISTICS角色来更新数据字典的系统统计信息。

与表(table)、索引(index)或字段(column)的统计信息不同,当系统统计信息更新后,Oracle不会使已经解析好的SQL语句无效。所有新的SQL语句会用新的统计信息来解析。

 

Oracle提供了两种选项来收集系统统计信息:
1. 工作量统计信息(workload statistics)
2. 非工作量统计信息(noworkload statistics)
这些选项使得收集物理数据库和工作量的信息更加容易:当收集工作量统计信息时,非工作量统计信息会被忽略。非工作量系统统计信息在数据库第一次启动时初始化为默认值的。

 

在Oracle 9i中引入的工作量统计信息,可以收集单个和多个块的读取时间,mbrc,CPU速度(cpuspeed)

,系统最大吞吐量和平均附属吞吐量(average slave throughput)。sreadtim、mreadtim和mbrc都是通过

比较一个工作量在开始和结束时的物理顺序和随机读取的数量来计算的。这些值是通过一些计数器来实现

的,这些计数器会在buffer cache完成同步读取请求时改变。由于这些计数器是存在于buffer cache中,

它们不仅包括I/O延迟,还包括关于latch争夺和任务转换时的等待。工作量统计信息因此依赖于工作量期

间的系统活动情况。如果系统被I/O限制——latch争夺和I/O吞吐量——它会反映到统计信息里,同时在使用

统计信息后,会在I/O方面得到一定的改善。更进一步,工作量统计信息的收集不会产生额外的开销。

 

 

在9.2版本中,加进了最大I/O吞吐量和平均附属吞吐量来为全表扫描(full table scan)设置更低的限制。

 

收集工作量统计信息

两种方法:


1. 运行dbms_stats.gather_system_stats('start')开始一个工作量期间(workload window),然后运行

dbms_stats.gather_system_stats('stop')来结束一个工作量期间(workload window)。
2. 运行dbms_stats.gather_system_stats('interval', interval=>n),其中n是分钟数,即统计信息在n

分钟后自动停止收集。

 

运行dbms_stats.delete_system_stats()来删除系统统计信息。工作量统计信息将会被删除并重置为默认

值非工作量统计信息。 

 

mbrc (Multiblock Read Count)
在10.2版本中,当执行全表扫描时,优化器使用了mbrc的值。默认地,操作系统允许的最大值是由

db_file_multiblock_read_count来设置的。但是,优化器使用mbrc=8来计算花费。“真正”的mbrc实际大

概是在buffer cache处理多块读取请求和如果某些块已经存在buffer cache中拆分成两个或多个之间,或

者当段大小(segment size)小于读取大小时。mbrc值会在工作量统计信息收集的一部分,所以对全表扫描

的评估很有帮助。

 

 

在收集工作量统计信息的过程中,如果在一系列工作量中没有执行表扫描,有可能mbrc和mreadtim都没有

收集到数据,这经常在OLTP系统中发生。另一方面,全表扫描经常发生在DSS系统中,但可能并行化运行

来绕过buffer cache。在那种情况,sreadtim仍然会被收集,因为使用buffer cache来执行了索引查找。

如果Oracle不能收集或者使收集到的mbrc或mreadtim生效,但已经收集了sreadtim和cpuspeed,那么只有

sreadtim和cpuspeed用于计算花费。全表扫描会通过使用以前版本的实现分析算法来计算花费。另一种替

代的方法是强制一个全表扫描来允许优化器收集数据来计算mbrc和mreadtim。

 

非工作量统计信息由I/O传输速度、I/O寻址时间和CPU速度(cpuspeednw)组成。工作量统计信息和非工

作量统计信息的主要区别是收集方法不同。
非工作量统计信息通过对所有数据文件提交随机读取来收集,而工作量统计信息使用计数器来记录数据库

活动的发生。isseektim表示它花费在定位磁盘头部来读取数据的时间。它的值一般在5到15微秒之间,依

赖于磁盘转速和磁盘或RAID的特定情况。I/O传输速度代表了操作系统从I/O系统中读取数据的速度。它的

值变化很大,从每秒几MB到上百MB都是可能的。Oracle使用相对保守的默认设置来设置I/O传输速度。

 

在Oracle 10g里,Oracle默认使用非工作量统计信息和CPU花费模型。在实例第一次启动时,非工作量统

计信息的值被初始化为:
ioseektim = 10ms
iotrfspeed = 4096 bytes/ms
cpuspeednw = 收集的值,随系统不同而变化
如果收集了工作量统计信息,那么非工作量统计信息就会被忽略,且Oracle会使用工作量统计信息。

 

要收集非工作量统计信息,不带参数运行dbms_stats.gather_system_stats()。在收集非工作量统计信息

的过程中,会对I/O系统产生负荷。这个收集过程可能需要几秒到几分钟,依赖于I/O性能和数据库大小。
这些信息要被分析和确认其一致性。在一些情况下,非工作量统计信息的值仍然保持原来的默认值。在那

种情况下,重复统计信息收集过程,或者手动设置为I/O系统根据使用dbms_stats.set_system_stats过程

得到的特定值。

 

 

无论何时,数据字典中的统计信息被修改了,统计信息的旧版本会被自动保存以供未来的还原。可以使用DBMS_STATS包的RESTORE过程来还原统计信息。这些过程使用一个时间戳作为参数,并还原到那个时刻。这是非常有用的,特别是新收集的统计信息导致了次优的执行计划,由此管理员想恢复到之前的统计信息。

 

有几个字典视图用来显示统计信息修改的时间。这些视图在决定还原统计信息的时间戳上非常有用。
1. 目录视图DBA_OPSTAT_OPERATIONS包含了使用DBMS_STATS收集于方案和数据库层面上的统计信息的历史记录。
2. 视图*_TAB_STATS_HISTORY(ALL,DBA或USER)包含了表的统计信息修改的历史记录。

 

旧的统计信息会在一定时间间隔后被自动清除,这个间隔由统计信息保留设置和系统的最近分析的时间来决定。保留时间是可以通过DBMS_STATS的ALTER_STATS_HISTORY_RETENTION过程来配置的。这个的默认值是31天,就是说你可以还原优化器的统计信息到过去的31天中的任何时刻。

 

当STATISTICS_LEVEL参数设置为TYPECAL或者ALL时,自动清除是启动的。如果自动清除是禁用的,那么旧的统计信息需要用PURGE_STATS过程来手动清除。
其他关于还原和清除统计信息的DBMS_STATS过程有:
1. PURGE_STATS:这个过程可以用来手动清除在一个时间戳上的旧版本的统计信息。
2. GET_STATS_HISTORY_RETENTION:这个函数可以得到当前统计信息历史保留时间的值。
3. GET_STATS_HISTORY_AVAILABILITY:这个函数可以得到统计信息历史记录最早的时间戳。用户不能还原统计信息到比这个时间更早的时刻。

 

当还原统计信息之前的版本时,有以下限制:
1. RESTORE过程不能还原用户定义的统计信息。
2. 当使用ANALYZE命令来收集统计信息时,不会保存统计信息的旧版本。

 

注意:
当使用DBMS_STATS时,如果你需要删除表中的所有记录,要用TRUNCATE来代替删除和重新创建一个相同的表。当表被删除时,自动直方图收集特性要使用的工作量信息和RESTORE_*_STATS过程要使用的已保存的统计信息历史记录将会失去。没有这些数据,这些特性都不能正常工作。

 

 

统计信息可以从数据字典导出或导入到用户自己的表中。这就使得你可以为相同的方案(schema)穿件多个版本的统计信息。它还可以使你能够从一个数据库复制统计信息到另一个数据库。你可能想这样做来把生产数据库中的统计信息复制到一个缩小比例的测试数据库中。

 

注意:
导出和导入统计信息是与EXP和IMP数据库工具不同的概念。

 

 

在导出统计信息之前,你首先需要创建一个表来保存统计信息。这个统计信息表是由DBMS_STATS.CREATE_STAT_TABLE来创建的。这个表创建之后,你就可以用DBMS_STATS.EXPORT_*_STATS过程来从数据字典中导出统计信息到你的统计信息表中。统计信息可以用DBMS_STATS.IMPORT_*_STATS过程来导入。

 

注意,优化器不会使用保存在用户自己的表中的统计信息。优化器使用的唯一统计信息是保存在数据字典中的统计信息。想要优化器使用用户自己的表的统计信息,你必须用统计信息导入过程将那些统计信息导入数据字典。
为了从一个数据库中移动统计信息到另一个数据库,你必须先在第一个数据库中导出统计信息,然后使用EXP和IMP工具或其他机制来复制统计信息表到第二个数据库,最后将统计信息导入第二个数据库。

 

注意:
EXP和IMP工具从数据库中连同表一起导出或导入优化器统计信息。有一种情况是例外的,如果一个表的一些字段是系统产生的名字,那么统计信息不会和数据一起导出。

 

 

还原统计信息的功能在某些方面与导入和导出统计信息的功能相似。一般说来,在以下情况,你应该使用还原:
1. 你想用旧的统计信息覆盖现在的统计信息。例如,还原优化器的行为到早些的时刻。
2. 你想数据库管理保留时间和清除统计信息的历史记录。
当以下情况,你应该使用EXPORT/IMPORT_*_STATS过程:
1. 你想体验统计信息的多个集合,并前后改变统计信息的值。
2. 你想将统计信息从一个数据库中转移到另一个数据库。例如,从生产库转移统计信息到测试库。
3. 你想保留一些知道的统计信息用来长期使用,而不只还原统计信息要求的保留时间。

 

表和方案的统计信息可以被上锁。一旦统计信息被上锁,那些统计信息就不能修改了,直到统计信息被解锁。这些上锁的过程在一个静态环境中特别有用,你可以保证统计信息从不改变。

DBMS_STATS包提供了两种过程来上锁,两种过程来解锁:
1. LOCK_SCHEMA_STATS
2. LOCK_TABLE_STATS
3. UNLOCK_SCHEMA_STATS
4. UNLOCK_TABLE_STATS

 

你可以用SET_*_STATISTICS来设置表、字段、索引和系统的统计信息。不建议这样设置统计信息,因为不精确的或者不一致的统计信息会导致糟糕的性能。

 

动态抽样的目的是为了通过决定更精确的预选择的估算和表与索引的统计信息来提高服务器性能。表与索引的统计信息包括表的块数量、应用索引块的数量、表的基数和相关连接字段的统计信息。这些更精确的估算可以让优化器产生更好性能的执行计划。

你可以用动态抽样来:

1. 当收集到的统计信息不能使用或者评估时可能导致重大错误时,评估单个表的预选择性。
2. 为没有统计信息的表和相关索引评估统计信息。
3. 为统计信息太旧的表和索引评估统计信息。

 

这个动态抽样特性是由OPTIMIZER_DYNAMIC_SAMPLING参数来控制的。为了使用动态抽样来自动收集所需的统计信息,这个参数应该设置为2或更大的值。默认值是2.

 

主要的性能属性是编译时间。Oracle在编译时决定一个查询是否能从动态抽样中得到性能上的好处。如果

是的话,一个递归的SQL语句会被调用来扫描表的块的随机样本,然后将相关的单表预选择来评估。在某些情况下,样本基数可以被利用来估计表的基数。任何相关的字段和索引的统计信息也会被收集。

 

依据OPTIMIZER_DYNAMIC_SAMPLING初始化参数的值,动态抽样查询会读取一定数量的块。

 

为了一个很快就执行完成的查询(几秒钟之内),你不会想用动态抽样来增加开销的。但是,动态抽样在以下情况可以获得好处:
1. 使用动态抽样可以得到更好的执行计划。
2. 查询的执行时间中,抽样只占很小一部分。
3. 查询会被执行很多次。


动态抽样可以应用在单个表的判定的子集,然后和估计的标准选择判定组合,这些标准判定是不会进行动态抽样的。

 

你可以通过OPTIMIZER_DYNAMIC_SAMPLING参数来控制动态抽样,参数值可以从0到10,默认值为2。
1. 0值意味着不使用动态抽样。
2. 增加参数的值导致更具进取的动态抽样运用,这是就表抽样的类型和I/O在抽样中的使用量来说的。
如果进行抽样的表没有插入、删除或更新,动态抽样可以重复进行。OPTIMIZER_FEATURES_ENABLE参数如果设置为9.2.0版本之前,可以关掉动态抽样特性。

 

 

如果动态抽样在游标提示或OPTIMIZER_DYNAMIC_SAMPLING初始化参数中使用到,抽样等级如下:
1. Level 0:不使用动态抽样。
2. Level 1:在以下条件符合时,对所有没有分析的表进行抽样:(1)查询中,至少有一个表没有分析

过;(2)这个没有分析过的表连接到另一个表或者出现在一个子查询或不能组合的视图中;(3)这个没

有分析过的表没有索引;(4)这个没有分析过的表的块比用来做动态抽样需要的块还多。需要被抽样的

块的数量是默认的动态抽样块(32)。
3. Level 2:对所有没分析过的表进行动态抽样。需要被抽样的块的数量是默认的动态抽样块数量的2倍。
4. Level 3:应用动态抽样到符合Level 2的条件的所有表,加上所有标准选择性评估使用了一些判定来

做动态抽样判定的表。需要被抽样的块的数量是默认的动态抽样块。对于没分析过的表,需要被抽样的块

的数量是默认的动态抽样块数量的2倍。
5. Level 4:应用动态抽样到符合Level 3的条件的所有表,加上单表判定引用到两个或以上的字段的所有表。需要被抽样的块的数量是默认的动态抽样块。对于没分析过的表,需要被抽样的块的数量是默认的动态抽样块数量的2倍。
6. Level 5,6,7,8,9:应用动态抽样到符合前面Level条件的所有表。分别使用2,4,8,32,128倍的默认动态抽样的块的数量。
7. Level 10:应用动态抽样到符合Level 9条件的所有表,并使用表的所有块进行判定。

 

如果动态抽样等级在使用DYNAMIC_SAMPLING优化器提示时,抽样等级如下:
1. Level 0:不使用动态抽样。
2. Level 1:需要被抽样的块的数量是默认的动态抽样块(32)。
3. Level 2,3,4,5,6,7,8,9:需要被抽样的块的数量分别为2,4,8,16,32,64,128,256倍动态抽样块默认数量。
4. Level 10:读取表的所有块。

 

当Oracle遇到一个表没有统计信息,Oracle就会动态地收集优化器所需的统计信息。但是,对于某些类型的表,Oracle是不会进行动态抽样的,包括远程表和外部表。在那种情况下,或者当动态抽样禁用时,优化器会为统计信息使用默认值,如下:


表统计信息:
基数(cardinality)=num_of_blocks * (block_size - cache_layer) / avg_row_len
平均行长度(average row length)=100字节
块的数量(number of blocks)=100或者基于extent映射的实际值
远程基数(remote cardinality)=2000行
远程平均行长度(remote average row length)=100字节


索引统计信息:
Levels=1
Leaf blocks=25
Leaf blocks/key=1
Data blocks/key=1
Distinct keys=100
Clustering factor=800

 

关于统计信息的数据字典:
*_TABLES
*_OBJECT_TABLES
*_TAB_STATISTICS
*_TAB_COL_STATISTICS
*_TAB_HISTOGRAMS
*_INDEXES
*_IND_STATISTICS
*_CLUSTERS
*_TAB_PARTITIONS
*_TAB_SUBPARTITIONS
*_IND_PARTITIONS
*_IND_SUBPARTITIONS
*_PART_COL_STATISTICS
*_PART_HISTOGRAMS
*_SUBPART_COL_STATISTICS
*_SUBPART_HISTOGRAMS
*号可以用DBA、ALL或USER代替。

 

字段统计信息可以保存为柱状图。这些柱状图提供了字段数据分布的精确估计。当数据库不对称时,柱状图提供了更精确的选择性估计,这样可以在不均匀分布的数据中得到一个最优执行计划。
Oracle为字段统计信息使用两种柱状图:height-balanced柱状图和frequency柱状图。柱状图的类型保存在*_TAB_COL_STATISTICS视图的HISTOGRAM字段中。这个字段的值可以是HEIGHT BALANCED,FREQUENCY或者NONE。

 

在一个height-balanced柱状图,字段的值被分成了区,以便每个区都含有大约相同的行数。这种柱状图

提供的有用信息是端点落在值的哪个范围。
考虑这样一种情况,字段C的值在1到100之间,柱状图有10个区间。如果字段C的值是均匀分布的,那么柱状图就像这样
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
1      10     20     30     40     50     60    70     80     90    100
数字是端点的值。

每个区间的行数是表的总行数的1/10.在这个例子中,4/10的行的值在60到100之间。


如果数据不是均匀分布的,柱状图可能像这样:
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
1     5    5     5    5     10   10   20    35   60   100
在这种情况下,该字段的值为5的行最多。只有1/10的行的值在60到100之间。
 

Height-balanced柱状图可以用*_TAB_HISTOGRAMS来查看,如下例子

 

在frequency柱状图中,字段的每个值对应柱状图中的一个单个区间。每个区间包含的数量是单个值的出现次数。Frequency柱状图是当不同值的数量少于或等于柱状图区间的数据量时自动创建来替代height-balanced柱状图的。Frequency柱状图可以用*_TAB_HISTOGRAMS来查看,如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值