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

在进行数据採集时我们有时会使用到其他输入參数。在这里我们对过程中的其他输入參数介绍。

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;

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;

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;

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
包或ANALYZE语句生成的统计信息。

DBA_TAB_STATISTICS

ALL_TAB_STATISTICS

USER_TAB_STATISTICS

描写叙述表的统计信息

DBA_INDEXES

ALL_INDEXES

USER_INDEXES

DBA 视图描写叙述在数据库中的全部表上的索引。

全部视图都描写叙述在用户可訪问的全部表上的索引。用户视图仅限于由用户拥有的索引。在这些视图中的统计信息有关的列包括由DBMS_STATS
包或ANALYZE语句生成的统计

在这里我们使用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统计信息管理介绍的更多相关文章

  1. JAVAEE——SSH项目实战06:统计信息管理、Spring注解开发和EasyUI

    作者: kent鹏 转载请注明出处: http://www.cnblogs.com/xieyupeng/p/7190925.html 一.统计信息管理   二.Spring注解开发 1.service ...

  2. openinstall渠道统计工具介绍

    大家好,今天给大家介绍一下如何使用openinstall 来实现APP 渠道统计,做运营推广的朋友应该对渠道统计并不陌生,之前一般都是让技术的同事打渠道包方式进行渠道统计,而且只有安卓才能打渠道包.o ...

  3. Oracle 统计信息介绍

      统计信息自动执行需要以下条件满足: dba_autotask_task 字段status值ENABLED dba_autotask_client 字段status值ENABLED dba_auto ...

  4. solr4.5分组查询、统计功能介绍

    说到分组统计估计大家都不会陌生,就是数据库的group by语句,但是当我们采用solr4.5全文检索时,数据库提供再好的sql语句都没有任何的意义了,那么在solr4.5中我们如何做到分组统计呢?其 ...

  5. App渠道统计方法全面解析 总有一种适合你

    一.App渠道统计对于App推广运营的重要性 (理解App渠道统计重要性的老司机,请直接移步到第二部分) App服务的竞争重点已经由功能竞争转向市场和运营的竞争,而App的推广与运营离不开App渠道统 ...

  6. Eclipse优化工具Optimizer for Eclipse

    第一次看到是Optimizer for Eclipse是在InfoQ 然后使用了一下,发现不错啊,我的好几年的破本都能比较快的启动Eclipse了 好了,废话不说了,来介绍一下Optimizer fo ...

  7. Excel统计发票和金税盘核对新版

    之前的博文:如何使用Excel表格状态栏动态查看统计,介绍了如何利用excel一拉就可以进行统计,和金税盘的月度统计统计.由于最近年月日显示成方框,所以作废了发票和对冲了上月的一张发票,导致这个月出现 ...

  8. SPSS统计分析过程包括描述性统计、均值比较、一般线性模型、相关分析、回归分析、对数线性模型、聚类分析、数据简化、生存分析、时间序列分析、多重响应等几大类

    https://www.zhihu.com/topic/19582125/top-answershttps://wenku.baidu.com/search?word=spss&ie=utf- ...

  9. 如何统计Ceph的RBD真实使用容量

    前言 ceph的rbd一直有个问题就是无法清楚的知道这个分配的空间里面到底使用了多少,这个在Jewel里面提供了一个新的接口去查询,对于老版本来说可能同样有这个需求,本篇将详细介绍如何解决这个问题 查 ...

随机推荐

  1. MySQL常见数据库引擎及比较?

    一:MySQL存储引擎简介 MySQL有多种存储引擎,每种存储引擎有各自的优缺点,大家可以择优选择使用:MyISAM.InnoDB.MERGE.MEMORY(HEAP).BDB(BerkeleyDB) ...

  2. 02-python进阶-文件操作

    新建一个文件 内容是从 0-9的整数 #coding:utf-8 f = open('1.txt','w') #r 只读 w 可写 a追加 for i in range(0,10): f.write( ...

  3. PHP 函数 ignore_user_abort()

    ignore_user_abort 设置与客户机断开是否会终止脚本的执行.   本函数返回 user-abort 设置的之前的值(一个布尔值). int ignore_user_abort ([ st ...

  4. NVIDIA NVML Driver/library version mismatch

    sudo rmmod nvidia_drm sudo rmmod nvidia_modeset sudo rmmod nvidia_uvm sudo lsof /dev/nvidia* confirm ...

  5. VirtualBox 安装XP虚拟机, 安装DB2

    个人随笔记录,也许说的不太清楚. 1. 用google搜索VirtualBox, 找到下载地址,下载,我的是win7,下载64bit的. 2. 下载后,安装VBox软件,这个没遇到问题. 3. 因为我 ...

  6. Good Bye 2017

    太菜了啊,一不小心就goodbye rating了 A. New Year and Counting Cards time limit per test 1 second memory limit p ...

  7. 紫书第一章训练1 D -Message Decoding

    Some message encoding schemes require that an encoded message be sent in two parts. The first part, c ...

  8. Welcome-to-Swift-08枚举 (Enumerations)

    枚举为一系相关联的值定义了一个公共的组类型.同时能够让你在编程的时候在类型安全的情况下去使用这些值. 如果你对C语言很熟悉,你肯定知道在C语言中枚举类型就是一系列具有被指定有关联名称的的整数值.但在S ...

  9. BZOJ 4816 [Sdoi2017]数字表格 ——莫比乌斯反演

    大力反演出奇迹. 然后xjb维护. 毕竟T1 #include <map> #include <ctime> #include <cmath> #include & ...

  10. 关于element-ui select组件change事件只要数据变化就会触发的解决办法

    使用select组件和表格组件结合起来用,但是发现在点击下一页的时候,由于select当中的数据发生了变化,所以也会触发select当中的change事件,但是我只希望在我主动改变select组件当中 ...