11g以后的oracle只使用CBO(基于成本的优化器)确定sql语句的执行计划,而CBO计算各种执行计划的成本依据就是系统里面存储的各种对象的统计信息。但是,统计信息并不是实时更新的,需要特定的动作去触发。这个主要是搜集统计信息的过程需要比较大的开销。
比较大众的统计信息
Dba_Ind_Statistics, Dba_Tab_Statistics, Dba_Tab_Col_Statistics获得统计信息。
对于表,通过查询dba_tables
Num_rows 表里的行数
Blocks 表使用的blocks数
Empty_blocks 表未使用过的空blocks数
Degree 默认扫描表的过程中的并行度
对于索引,通过查询dba_indexes
Blevel 索引存储的B树结构的高度,一层高度为0,一般情况下超过4需重建索引
Leaf_blocks 叶子节点的块数
Clustering_factor 聚簇因子,聚簇因子反映了以该索引数据的顺序为准,表数据在物理块存储的聚集度。最好的情况下,聚簇因子等于表的blocks数,最坏的情况下,聚簇因子等于表的num_rows数。
Distinct_key,索引中数值个数等等。
对于列,通过查询dba_tab_columns
Num_distinct,唯一数值的数目
Low_value,high_value 最大值,最小值
Num_nulls 空值个数
Histogram 直方图等。
如何搜集统计信息
Oracle主要提供了两种方法
1、 analyze命令。
2、 dbms_stat包。
Analyze方式一直以来不被推荐,oracle官方一直推荐使用dbms_stat包的方式。
Dbms_stat方式主要优点是可以指定并行度,可以自动执行(通过alter table monitor).
但搜集表的行迁移和行连接、验证存储格式合法性以及freelist上的空block信息,则必须使用analyze才能做得到。
Dbms_stat包的使用
Dbms_stat.gather_table_stats()
Dbms_stat.gather_schema_stats()
Dbms_stat.gather_index_stats()
Dbms_stat.gather_database_stats()
Dbms_stat.gather_system_stats()
下面列一下常用的语句
搜集schema的。
dbms_stats.gather_schema_stats(ownname => 'wjf',
options =>'gather auto',
method_opt => 'for all columns size repeat',
cascade => 'true',
degree => '4')
ownername 就是schema的名字。
Options gather auto 重新搜集没有统计过或统计数据过期的对象。
Gatherempty 指搜集没有统计过的对象。
Gatherstale只统计修改量超过10%的表。
Gather 重新搜集整个schema。
Method_opt 这个是确定在哪些列上建立柱状图的选项。(只列出了for all columns相关的)
Forall columns size repeat.只在原本有柱状图的列上进行柱状图分析重建。
Forall columns size skewonly.分析所有列数据的分布情况,根据此情况决定在哪些列上建立柱状图。比较耗费系统资源。
Forall columns size auto。根据列数据分布情况和负载情况决定如何建立柱状图。
Casecade 是否要同时搜集索引的统计信息,默认为false。
Degree 搜集信息时的并行度,主要取决与你系统中cpu的个数。
搜集table的。
execdbms_stats.gather_table_stats(ownname => 'WJF',
tabname => 'WJF_SM_USER',
estimate_percent => 100,
cascade => true,
degree => 4)
estimate_percent 这个是设置生成统计信息的采样比率,大小从0-100。默认值的话是dbms_stats.auto_sample_size,即由oracle自行决定。
搜集database的
dbms_stats.gather_database_stats(method_opt => 'for all columns size auto',
cascade => true,
degree => 7)
另外如果在安装数据库的时候,勾选了自动维护,则系统会自己建立一个搜集统计信息的任务。
Analyze
在以下两种情况需要使用anylyze。
1、 需要搜集行迁移行连接情况
2、 需要搜集空闲链表中的块数目
analyzetable wjf_sm_user computestatisticsfortable;
--针对表收集信息
analyzetable wjf_sm_user computestatisticsforallcolumns;
--针对表字段收集信息
analyzetable t3 computestatisticsforallindexescolumns;
--收集索引字段信息
analyzetable t4 computestatistics;
--收集表,表字段,索引信息
analyzetable wjf_sm_user computestatisticsforallindexes;
--收集索引信息