Optimizer统计信息管理介绍
1. 前言
在我们的日常维护中受理一些一直以来运行得非常好的系统,突然有一天用户反馈没有做不论什么操作,系统的某个功能模块或者是某个报表曾经仅仅须要几秒。但如今须要几分钟或更长的时间都没有返回结果。在这种情况下,我们一般会分析SQL语句。会发现这个SQL的运行计划已经发生改变,在硬件环境未发生变化的情况下。运行计划发生变化多数原因是因为表的统计信息发生了变化,原本使用的某个索引突然间没有被使用。或者使用了较差的索引,这都是因为统计信息不准备确引起的,因此我们有必要了解统计信息的管理和维护。更好的优化SQL和性能问题处理。
2. 什么是统计信息
统计信息是描写叙述该数据库中的数据和数据库中的对象的集合。这些统计数据所使用的优化选择对每一个SQL语句的最佳运行计划。统计信息存储在数据字典,而且能够使用数据字典视图来訪问诸如USER_TAB_STATISTICS。优化统计数据是从通过V
 $视图中显示的性能统计信息不同。在V$视图中的信息涉及该系统的状态和SQL负载上运行它。
Oracle 10g之后。Query Optimizer就已经将CBO作为默认优化器,而且Oracle官方不再支持10G曾经的RBO服务。可是,通过优化器參数OPTIMIZER_MODE,我们能够控制Oracle优化器生成不同模式下的运行计划。数据库中的对象能够是不断变化的,统计数据必须定期更新。以便准确地描写叙述这些数据库对象,统计都是由Oracle自己主动地或手动使用DBMS_STATS包完毕,DBMS_STATS还提供了用于管理统计程序。能够保存和恢复副本统计。
能够从一个系统导出统计数据到还有一个系统。
比如,你能够从一个生产数据库将统计信息导出到一个測试系统。此外,我们还能够锁定统计信息。防止这些统计数据的变化统计。
图1存储统计信息字典视图
2.1. 表统计信息
表统计信息包含表中行的数量信息,表使用数据块的数量,以及行在表中的平均行长度。优化器使用这些信息,结合其他统计信息,以计算各种操作的运行计划成本,并预计行的操作将产生的数量。比如,一个表存取的成本是使用数据块和參数DB_FILE_MULTIBLOCK_READ_COUNT的值进行计算,表的统计信息能够在字典视图USER_TAB_STATISTICS查看。
2.2. 列统计信息
个不同的相等谓词,那么优化器,假定数据分布是均匀的,预计的基数为表中的行数不同的值除以该列,即100
 / 10 = 10。
图2使用基本表和列统计基数计算
2.3. 索引统计信息
索引统计信息提供索引中不同值的数据信息。叶块中的索引数,索引的深度和集群因子数目的数量。优化程序会使用这些信息连同其它统计信息来确定索引訪问的成本。
比如优化器使用B树索引。将会使用叶块数和表统计中的num_rows确定索引范围扫描的成本。
2.4. 直方图统计信息
直方图是一种对被管理对象某一方面质量进行管理的描写叙述工具,在Oracle中自然它也是对Oracle中某个对象质量的描写叙述工具,这个对象就是Oracle中最重要的东西——“数据”。
在Oracle中直方图是一种对数据分布质量情况进行描写叙述的工具。它会依照某一列不同值出现数量多少。以及出现的频率高低来绘制数据的分布情况,以便可以指导优化器依据数据的分布做出正确的选择。在某些情况下,表的列中的数值分布将会影响优化器使用索引还是运行全表扫描的决策。当WHERE子句的值具有不成比例数量的数值时,将出现这样的情况。使得全表扫描比索引訪问的成本更低。
这样的情况下假设WHERE子句的过滤谓词列之上有一个合理的,正确的直方图,将会对优化器使用索引还是全表扫描发挥巨大的作用,使得SQL语句运行成本最低从而提升性能。
在分析表或索引时,直方图用于记录数据的分布。通过获得该信息,基于成本的优化器就能够决定使用将返回少量行的索引。而避免使用基于限制条件返回很多行的索引。
直方图的使用不受索引的限制,能够在表的不论什么列上构建直方图。
%的记录。
通常情况下在下面场合中建议使用直方图:
1) 当Where子句引用了列值分布存在明显偏差的列时:当这样的偏差相当明显时。以至于 WHERE子句中的值将会使优化器选择不同的运行计划。
这时应该使用直方图来帮助优化器来修正运行路径。(注意:假设查询不引用该列,则创建直方图没有意义)
行。Oracle
将会以一种使第一个联接的结果集(集合基数)尽可能小的方式将表联接起来。通过在中间结果集中携带更少的负载。查询将会执行得更快。为了使中间结果最小化,优化器尝试在 SQL执行的分析阶段评估每一个结果集的集合基数。在偏差的列上拥有直方图将会极大地帮助优化器做出正确的决策。
如优化器对中间结果集的大小做出不对的推断,它可能会选择一种未达到最优化的表联接方法。因此向该列加入直方图常常会向优化器提供使用最佳联接方法所需的信息。
Oracle利用直方图来提高非均匀数据分布的选择率和技术的计算精度。可是实际上Oracle会採用另种不同的策略来生成直方图:当中一种是针对包括非常少不同值的数据集;还有一种是针对包括非常多不同的数据集。
Oracle会针对第一种情况生成频率直方图。针对另外一种情况生成高度均衡直方图。通常情况下当BUCTET
 < 表的NUM_DISTINCT值得到的是HEIGHT BALANCED(高度平衡)直方图。而当BUCTET
 > 表的NUM_DISTINCT值的时候得到的是FREQUENCY(频率)直方图。
3. 管理统计信息
Oracle 建议启用自己主动优化程序统计信息收集。在这样的情况下,数据库会自己主动收集没有被收集过的统计信息或过时的统计信息。假设一个新表须要收集统计信息,数据库会收集表和关联的索引。
自己主动优化统计信息收集程序执行DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC调用,数据统计信息收集过程DBMS_STATS.GATHER_DATABASE_STATS,该过程使用GATHER
 AUTO选项收集数据库表的信息和索引信息。使统计信息为最新状态。GATHER_DATABASE_STATS_JOB_PROC过程进行统计信息收集,过程会优先数据库对象统计收集,所以在收集统计信息期间要对数据库的对象更新操作时。须要关闭自己主动统计收集作业。
3.1. 启用和禁用自己主动统计信息收集
Oracle自己主动维护任务基础结构(称为 AutoTask)调度程序会在维护窗体中自己主动执行该任务。
默认情况下,每周六的晚上。自己主动优化程序统计信息收集作为
 AutoTask 的一部分执行,默认启用的在全部的提前定义的维护窗体中执行。
假设对于一些原因自己主动优化程序统计信息收集被禁用,能够使用DBMS_AUTO_TASK_ADMIN包手动启用:
BEGIN
DBMS_AUTO_TASK_ADMIN.ENABLE(
client_name => 'auto optimizer stats collection'
, operation => NULL
, window_name => NULL
);
END;
/
假设採用手动管理方式收集统计信息,相同能够使用能够使用DBMS_AUTO_TASK_ADMIN包手动禁用作业:
BEGIN
DBMS_AUTO_TASK_ADMIN.DISABLE(
client_name => 'auto optimizer stats collection'
, operation => NULL
, window_name => NULL
);
END;
/
3.2. DBMS_STATS统计信息管理
对于不断变化的数据库对象。必须定期收集统计数据以便他们准确地描写叙述数据库对象。Oracle推荐使用DBMS_STATS过程 包收集统计信息,并代替如今已经过时的统计信息收集命令ANALYZE 。DBMS_STATS 包包括超过 50 不同的过程。用于收集和管理统计。并且最重要的过程是 GATHER_
 * _STATS 程序。
这些过程能够用于收集和管理表、 列和索引的统计信息,必须使用对象的全部者或有不论什么具有系统特权的DBA 角色执行这些程序,下面是DBMS_STATS包中收集统计信息涉及到的过程。
| 
 名称  | 
 用途描写叙述  | 
| 
 GATHER_INDEX_STATS  | 
 收集特定用户下指定索引列的统计信息  | 
| 
 GATHER_TABLE_STATS  | 
 收集特定用户指定表上表行,列和索引列的统计信息  | 
| 
 GATHER_SCHEMA_STATS  | 
 收集特定用户全部对像的统计信息  | 
| 
 GATHER_DICTIONARY_STATS  | 
 收集数据库全部数据字典统计信息  | 
| 
 GATHER_DATABASE_STATS  | 
 收集数据库全部对象统计信息  | 
3.2.1. 手动採集表统计信息
个不同的參数。我们在收集表的统计信息时,仅仅需指定ownname和tabname这两个參数,过程包就能够执行。
假设表是分区表还须要指分区名称。比如我们对住院费用记录表进行统计信息进行收集,使用下面方式就能够收集到该表的统计信息。
SQL> begin
2 dbms_stats.gather_table_stats(ownname => 'ZLHIS',
3 tabname => '药品库存');
4 end;
5 /
PL/SQL procedure successfullycompleted
在进行数据採集时我们有时会使用到其他输入參数。在这里我们对过程中的其他输入參数介绍。
l ESTIMATE_PERCENT
ESTIMATE_PERCENT參数确定用来计算统计信息行数的百分比,最准确的统计信息收集处理是收集表中的全部行。Oracle 11g使用一种新的採样算法。基于哈希值并提供准确的统计信息。这样的新方法精度接近全部行(100%)样品。但顶多消耗10%样品的成本。
ESTIMATE_PERCENT的默认值设置为AUTO_SAMPLE_SIZE。将使用这样的新算法。
GATHER_
 * _STATS 程序。
我们在对ZLHIS对象收集统计信息时,将ESTIMATE_PRECENT參数设置为较低的值,一般是10%的方式收集,这样做以确保将收集统计数据的结果迅速。
当然为了数据库得到更准备统计信息。Oracle强烈建议从
 Oracle 11g 起使用ESTIMATE_PRECENT參数的默认值收集统计信息,该參数的取值范围为取值范围[0.000001-100]。
演示样例:參数ESTIMATE_PERCENT=10以病人医嘱发送数据表数据10%的比例进行数据收集。
begin
dbms_stats.gather_table_stats(ownname => 'ZLHIS',
tabname => '病人医嘱发送',
estimate_percent=> 10,
method_opt => 'for all columns size skewonly',
force => true,
cascade => true,
degree => 4);
end;
l METHOD_OPT
这个參数最常见的功能就是控制直方图的收集方式,但实际上它的功能远不及此,它的实际功能例如以下所看到的:
ü 控制哪些列收集主要的统计信息
ü 收集直方图,
ü 收集扩展的统计信息
Method_opt 參数使用方法分为两个部分,例如以下图所看到的:
FOR ALL [indexed | hidden] columns这一部分控制着哪些列将会收集列的基本统计信息。目标列上的最小值,最大值。列上不同值的数量。空值的数量等等。
系统默认值为FOR
 ALL COLUMNS,它将收集表上全部列(包含隐藏列)的主要的统计信息。
指定FOR
 ALL INDEXED COLUMNS 仅仅收集含有索引字段列的基本统计信息。
一般不推荐使用这个选项值,由于在数据库环境中的全部 SQL语句所使用的字段,比方SELECT
后面的字段,WHERE后面字段,GROUP BY中的字段,并不仅仅是会引用含有索引的字段。
指定FOR
 ALL HIDDEN COLUMNS收集全部不可见字段基本统计信息,相同在收集统计信息时不推荐使用这个选项值。这个选项值通常仅仅用于在一个全部列的统计信息都是准确的表中新增了一个或几个不可见或者说是虚拟的列,仅仅须要收集这个或者这几个不可见列的统计信息,而不再反复去其它列的统计信息。
Size [size_clause]这一部分控制收集直方图的方式。SIZE
后面能够有下面选项:
AUTO Oracle自己决定依据列的统计信息(sys.col_usage$)以及列的数据倾斜程度(均匀分布程度)决定哪些列须要收集直方图。
最大为
 254 (,即SIZE 1
意味着不建立直方图,假设已经有直方图的列则会删除该列的直方图。
。这钟方式可能不会取得好的效果。
SKEWONLY 仅仅在数据不均匀分布的列上收集直方图。
演示样例:參数METHOD_OPT = 'FOR ALL COLUMNS SIZESKEWONLY'收集病人医嘱分布不均匀列的直方图统计信息。
begin
dbms_stats.gather_table_stats(ownname => 'ZLHIS',
tabname => '病人医嘱发送',
estimate_percent => 10,
method_opt => 'for all columns size skewonly',
force => true,
cascade => true,
degree => 4);
end;
l DEGREE
就可以。对大数据对象的能够使用DBMS_STAT.DEFAULT_DEGREE參数由数据库自己主动分配并行度。
个进程收集病人医嘱发送记录的统计信息。
begin
dbms_stats.gather_table_stats(ownname => 'ZLHIS',
tabname => '病人医嘱发送',
estimate_percent => 10,
method_opt => 'for all columns size skewonly',
force => true,
cascade => true,
degree => 4);
end;
l CASCADE
在系统上没有执行过索引统计信息收集。使用CASCADE选项相当于在除了收集表和列统计并同一时候执行 GATHER_INDEX_STATS收集索引统计信息。使用參数DBMS_STATS.AUTO_CASCADE由ORACLE确定是否收集索引统计信息要,參数设置为TRUE强制收集全部索引统计信息,在缺省情况下CASCADE參数值为FALSE。
演示样例:强制收集病人医嘱发送上的全部索引统计信息。
begin
dbms_stats.gather_table_stats(ownname => 'ZLHIS',
tabname => '病人医嘱发送',
estimate_percent => 10,
method_opt => 'for all columns size skewonly',
force => true,
cascade => true,
degree => 4);
end;
3.2.2. 锁定和解锁一个表统计信息
在某些情况下我们须要锁定一个特定表的统计息不被更新。以保证运行计划的准确性,我们须要使用DBMS_STATS.LOCK_TABLE_STATS锁定统计信息。
要锁定一个表的统计信息我们仅仅须要传入表的拥有者和表名就能够锁定该用户表的统计信息。
反之我们要解锁一个锁定的用户对象使用DBMS_STAT.UNLOCK_TABLE_STATS解锁锁定的统计信息。
演示样例:锁定ZLHIS用户下药品收发记录统计信息。
begin
DBMS_STATS.LOCK_TABLE_STATS(ownname =>'ZLHIS' , tabname =>'药品收发记录' );
end;
演示样例:解锁被锁定的ZLHIS用户下药品收发记录统计信息。
begin
DBMS_STATS.UNLOCK_TABLE_STATS(ownname =>'ZLHIS' , tabname =>'药品收发记录' );
end;
3.2.3. 删除统计信息
有的时候我们在收集了统计信息却发现新的统计信息比旧的统计信息还要差,因此我们须要将统计信息删除又一次收集。下面列出删除统计信息相关过程。
| 
 名称  | 
 用途描写叙述  | 
| 
 DELETE_INDEX_STATS  | 
 删除特定用户下指定索引列的统计信息  | 
| 
 DELETE_TABLE_STATS  | 
 删除特定用户指定表上表行,列和索引列的统计信息  | 
| 
 DELETE _SCHEMA_STATS  | 
 删除特定用户全部对像的统计信息  | 
| 
 DELETE _DICTIONARY_STATS  | 
 删除数据库全部数据字典统计信息  | 
| 
 DELETE _DATABASE_STATS  | 
 删除数据库全部对象统计信息  | 
演示样例:删除ZLHIS用户药品收发记录表统计信息
begin
DBMS_STATS.delete_table_stats(ownname =>'ZLHIS' , tabname =>'药品收发记录' )
end;
3.3. 与统计相关的视图
全部与数据表,列和索引相关的统计信息都能够通过Oracle数据库字典视图查询,常使用的视图有:
| 
 名称  | 
 用途描写叙述  | 
| 
 DBA_TAB_COLUMNS ALL_TAB_COLUMNS USER_TAB_COLUMNS  | 
 DBA视图描写叙述数据库中全部表列。用户视图仅限于由用户拥有的表,在这些视图中统计信息有关的列由DBMS_STATS  | 
| 
 DBA_TAB_STATISTICS ALL_TAB_STATISTICS USER_TAB_STATISTICS  | 
 描写叙述表的统计信息  | 
| 
 DBA_INDEXES ALL_INDEXES USER_INDEXES  | 
 DBA 视图描写叙述在数据库中的全部表上的索引。 全部视图都描写叙述在用户可訪问的全部表上的索引。用户视图仅限于由用户拥有的索引。在这些视图中的统计信息有关的列包括由DBMS_STATS  | 
在这里我们使用USER_TAB_STATISTICS视图为例,先了解视图USER_TAB_STATISTICS字段的含义后,使用该视图查看表药品收发记录统计信息。
USER_TAB_STATISTICS
| 
 例名  | 
 描写叙述  | 
| 
 TABLE_NAME  | 
 表名  | 
| 
 PARTITION_NAME  | 
 分区表名  | 
| 
 PARTITION_POSITION  | 
 分区位置  | 
| 
 SUBPARTITION_NAME  | 
 子分区表名  | 
| 
 SUBPARTITION_POSITION  | 
 子分区位置  | 
| 
 OBJECT_TYPE  | 
 对象类型(表,分区。子分区)  | 
| 
 NUM_ROWS  | 
 对象中的行记录数  | 
| 
 BLOCKS  | 
 对象使用的数据块数  | 
| 
 EMPTY_BLOCKS  | 
 对象中的空块数  | 
| 
 AVG_SPACE  | 
 对象中的平均可用空间  | 
| 
 CHAIN_CNT  | 
 对象中的行连接数  | 
| 
 AVG_ROW_LEN  | 
 对象中行记录的平均长度  | 
| 
 AVG_SPACE_FREELIST_BLOCKS  | 
 在一个自由列表的全部块的平均可用空间  | 
| 
 NUM_FREELIST_BLOCKS  | 
 在一个自由列表的块的数量  | 
| 
 AVG_CACHED_BLOCKS  | 
 在缓冲区快速缓存中的平均块数  | 
| 
 AVG_CACHE_HIT_RATIO  | 
 平均缓存对象的命中率  | 
| 
 SAMPLE_SIZE  | 
 採样样本  | 
| 
 LAST_ANALYZED  | 
 最后一次表分析时间  | 
| 
 GLOBAL_STATS  | 
 没有合并的分区计算的统计?  | 
| 
 USER_STATS  | 
 统计信息是否为用户输入  | 
| 
 STATTYPE_LOCKED  | 
 锁定统计信息类型  | 
| 
 STALE_STATS  | 
 统计信息是否过期  | 
比如。我们如今查询药品收发记录的相关统计信息的行数。表分析的採样样本,统计信息是否被锁定,统计信息是否过期这几种情况,能够使用字段NUM_ROWS,SAMPLE_SIZE,LAST_ANALYZED,STATTYPE_LOCKED,STALE_STATS获取相关信息。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2Vuemhvbmd5YW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
4. 结束语
通过我们对统计的了解。已经知道统计信息对Oracle是很重要的,它会收集数据库中对象的具体信息。并存储在对应的数据字典里。依据这些统计信息,优化器能够对每一个SQL去选择最好的运行计划,统计信息收集作业由Oracle定期自己主动收集,但某些特殊情况下还须要我们进行手动维护和管理。比如我们产品升级后及时手动採集数据库的统计信息是很有必要的。
Optimizer统计信息管理介绍的更多相关文章
- JAVAEE——SSH项目实战06:统计信息管理、Spring注解开发和EasyUI
		
作者: kent鹏 转载请注明出处: http://www.cnblogs.com/xieyupeng/p/7190925.html 一.统计信息管理 二.Spring注解开发 1.service ...
 - openinstall渠道统计工具介绍
		
大家好,今天给大家介绍一下如何使用openinstall 来实现APP 渠道统计,做运营推广的朋友应该对渠道统计并不陌生,之前一般都是让技术的同事打渠道包方式进行渠道统计,而且只有安卓才能打渠道包.o ...
 - Oracle 统计信息介绍
		
统计信息自动执行需要以下条件满足: dba_autotask_task 字段status值ENABLED dba_autotask_client 字段status值ENABLED dba_auto ...
 - solr4.5分组查询、统计功能介绍
		
说到分组统计估计大家都不会陌生,就是数据库的group by语句,但是当我们采用solr4.5全文检索时,数据库提供再好的sql语句都没有任何的意义了,那么在solr4.5中我们如何做到分组统计呢?其 ...
 - App渠道统计方法全面解析 总有一种适合你
		
一.App渠道统计对于App推广运营的重要性 (理解App渠道统计重要性的老司机,请直接移步到第二部分) App服务的竞争重点已经由功能竞争转向市场和运营的竞争,而App的推广与运营离不开App渠道统 ...
 - Eclipse优化工具Optimizer for Eclipse
		
第一次看到是Optimizer for Eclipse是在InfoQ 然后使用了一下,发现不错啊,我的好几年的破本都能比较快的启动Eclipse了 好了,废话不说了,来介绍一下Optimizer fo ...
 - Excel统计发票和金税盘核对新版
		
之前的博文:如何使用Excel表格状态栏动态查看统计,介绍了如何利用excel一拉就可以进行统计,和金税盘的月度统计统计.由于最近年月日显示成方框,所以作废了发票和对冲了上月的一张发票,导致这个月出现 ...
 - SPSS统计分析过程包括描述性统计、均值比较、一般线性模型、相关分析、回归分析、对数线性模型、聚类分析、数据简化、生存分析、时间序列分析、多重响应等几大类
		
https://www.zhihu.com/topic/19582125/top-answershttps://wenku.baidu.com/search?word=spss&ie=utf- ...
 - 如何统计Ceph的RBD真实使用容量
		
前言 ceph的rbd一直有个问题就是无法清楚的知道这个分配的空间里面到底使用了多少,这个在Jewel里面提供了一个新的接口去查询,对于老版本来说可能同样有这个需求,本篇将详细介绍如何解决这个问题 查 ...
 
随机推荐
- Python_Virtualenv及Pycharm配置
			
Virtualenv存在的意义 在Python使用过程中,你是否有遇到过同时需要开发多个应用的情况? 假设A应用需要使用DJango1.X版本,而B应用需要使用DJango2.X的版本,而你全局开发环 ...
 - [adb 学习篇] python将adb命令集合到一个工具上
			
https://testerhome.com/topics/6938 qzhi的更全面,不过意思是一样的,另外补充一个开源的https://github.com/264768502/adb_wrapp ...
 - 【软件工程】Word frequency program
			
一.开始写代码前的规划: 1.尝试用C#来写,之前没有学过C#,对于C++也不熟,所以打算先花1天的时间学习C# 2.整个程序基本分为文件遍历.单词提取.单词匹配.排序.输出几个模块,各个模块大致时间 ...
 - 【java基础 17】集合中各实现类的性能分析
			
大致的再回顾一下java集合框架的基本情况 一.各Set实现类的性能分析 1.1,HashSet用于添加.查询 HashSet和TreeSet是Set的两个典型实现,HashSet的性能总是比Tree ...
 - 多元线性回归(pandas/scikit-learn)
			
import pandas as pd from sklearn.cross_validation import train_test_split from sklearn.linear_model ...
 - Luogu【P1725】琪露诺(单调队列,DP)
			
本文是笔者第二篇解题报告.从现在开始,会将练的一些题发到博客上并归类到"解题报告"标签中. 琪露诺是这样一道题 这道题可以用纯DP做,但是据说会超时.(为什么?看起来过河这题比它数 ...
 - [AtCoderContest075F]Mirrored
			
[AtCoderContest075F]Mirrored 试题描述 For a positive integer \(n\), we denote the integer obtained by re ...
 - volatile的用法
			
在再有人问你Java内存模型是什么,就把这篇文章发给他中我们曾经介绍过,Java语言为了解决并发编程中存在的原子性.可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如synchronized ...
 - 用户认证系统 django.contrib.auth模块
			
一 导入auth模块 from django.contrib.auth.models import User from django.contrib import auth auth模块的操作针对的就 ...
 - linux监控平台搭建-内存
			
linux监控平台搭建-内存 上一篇文章说的硬盘.就写一下.更加重要的东西.在手机上面是RAM.机器是memory.内存是按照字节编址.每个地址的存储单元可以存放8bit的数据.cpu 通过内存地址获 ...