签到成功

知道了

CNDBA社区CNDBA社区

DM7 达梦数据库 查询优化 -- 统计信息

2019-09-05 14:47 4128 0 原创 DM 达梦
作者: dave

1 统计信息概述

对象统计信息描述数据是如何在数据库中存储的。统计信息是优化器的代价计算的依据,可以帮助优化器较精确地估算成本,对执行计划的选择起着至关重要的作用。

http://www.cndba.cn/cndba/dave/article/3644
http://www.cndba.cn/cndba/dave/article/3644

DM采用的是基于代价的优化器(CBO:Cost-Based Optimization),计算各种“可能”执行计划的“代价”,即COST,从中选用COST最低的执行方案,作为实际运行方案。它依赖数据库对象的统计信息,统计信息的准确与否会影响CBO做出最优的选择。http://www.cndba.cn/cndba/dave/article/3644

统计信息主要描述了数据库中表、索引的大小、规模、数据分布状况等的一类信息。比如,表的行数、块数、平均每行的大小、索引的leaf blocks、索引字段的行数、不同值的大小等。CBO正是根据这些统计信息数据,计算出不同访问路径、不同join 方式下,各种执行计划的成本,最后选择出成本最小的执行计划执行查询操作。

达梦数据库的统计信息分三种类型:表统计信息、列统计信息、索引统计信息。通过直方图来表示。统计信息生成过程分以下三个步骤:

1. 确定采样的数据:根据数据对象,确定需要分析哪些数据。

1) 表:计算表的行数、所占的页数目、平均记录长度
2) 列:统计列数据的分布情况
3) 索引:统计索引列的数据分布情况http://www.cndba.cn/cndba/dave/article/3644http://www.cndba.cn/cndba/dave/article/3644

2. 确定采样率
根据数据对象的大小,通过内部算法,确定数据的采样率。采样率与数据量成反比。

http://www.cndba.cn/cndba/dave/article/3644

3. 生成直方图
有两种类型的直方图:频率直方图和等高直方图。根据算法分析表的数据分布特征,确定直方图的类型。频率直方图的每个桶(保存统计信息的对象)的高度不同,等高直方图每个桶的高度相同。例如,对列生成统计信息,当列值分布比较均匀时,会采用等高直方图,否则,采用频率直方图。http://www.cndba.cn/cndba/dave/article/3644

用户也可以通过修改 OPTIMIZER_DYNAMIC_SAMPLING 参数值在缺乏统计信息时进行动态统计信息收集。

统计信息包含几个重要的宏观数据:

1)表所占的数据页数目
2)实际使用数据页数,
3)B树的高度 ,(对于聚集索引表)http://www.cndba.cn/cndba/dave/article/3644

无论做不做统计信息收集,表的当前记录数永远是有效的,因为系统自动维护了表的记录总数,这一点与大部分其他DBMS系统有所差别。

另外,如果做了列级或者索引的收集,那么统计信息还包括下列信息:

COLID 列的ID
SQL_PL_TYPE 数据类型
N_TOTAL 总记录数
N_SAMPLE 采样记录数
N_DISTINCT 不同值数
N_NULL 空值数
V_MIN 最小值
V_MAX 最大值
BLEVEL B树的高度
N_LEAF_PAGES 叶子段的页数目
N_LEAF_USED_PAGES 叶子段实际使用的页数目
CLUSTER_FACTOR 聚集因子

http://www.cndba.cn/cndba/dave/article/3644

2 统计信息管理

2.1 DBMS_STATS包说明

DM7管理统计信息有两种方法:一是通过一些存储过程,二是使用 DBMS_STATS 包来收集统计、删除信息,将收集的统计信息记录在数据字典中。
推荐使用DBMS_STATS包来收集,有别于存储过程,通过这个工具包收集可以指定采用率,在数据分布极不均匀的情况下,提高统计信息的采用率,有助于提供更精确的统计信息。

DBMS_STATS包含以下存储过程:

http://www.cndba.cn/cndba/dave/article/3644

1)COLUMN_STATS_SHOW: 根据模式名,表名和列名获得该列的统计信息。返回两个结果集:一个是列的统计信息;另一个是直方图的统计信息。
2)TABLE_STATS_SHOW: 根据模式名,表名获得该表的统计信息。
3)INDEX_STATS_SHOW: 根据模式名,索引名获得该索引的统计信息。返回两个结果集:一个是索引的统计信息;另一个是直方图的统计信息。
4)GATHER_TABLE_STATS: 根据设定的参数,收集表、表中的列和表上的索引的统计信息。其中,对于表,只搜集表的总行数、总的页数、已经使用的页数等基本信息。
5)GATHER_INDEX_STATS: 根据设定的参数,收集索引的统计信息。
6)GATHER_SCHEMA_STATS: 收集模式下对象的统计信息。
7)DELETE_TABLE_STATS: 根据设定参数,删除与表相关对象的统计信息。
8)DELETE_SCHEMA_STATS: 根据设定参数,删除模式下对象的统计信息。
9)DELETE_INDEX_STATS: 根据设定参数,删除索引的统计信息。
10)DELETE_COLUMN_STATS: 根据设定参数,删除列的统计信息。
11)UPDATE_ALL_STATS: 更新已有的统计信息。
12)CONVERT_RAW_VALUE: 根据设定参数,删除列的统计信息。

以下对象不支持统计信息:

1. 外部表、DBLINK 远程表、动态视图表、记录类型数组所用的临时表。
2. 所在表空间为 OFFLINE 的对象。
3. 位图索引,位图连接索引、虚索引、全文索引、空间索引、数组索引、无效的索引。
4. BLOB、IMAGE、LONGVARBINARY、CLOB、TEXT、LONGVARCHAR、自定义类型列和空间类型列等列类型。

2.2 操作示例

2.2.1统计信息收集

#收集表的统计信息, 该过程还有很多其他参数,具体可以参考官方手册
SQL>call dbms_stats.gather_table_stats(OWNNAME='CNDBA',TABNAME='EMPLOYEE',DEGREE=3,ESTIMATE_PERCENT=50);
DMSQL executed successfully
used time: 146.692(ms). Execute id is 65.
SQL> 


#收集索引的统计信息:
SQL> create index idxid on CNDBA.EMPLOYEE(employee_id);
executed successfully
used time: 13.523(ms). Execute id is 67.
SQL> call dbms_stats.gather_index_stats(OWNNAME='CNDBA',INDNAME='IDXID',DEGREE=3,ESTIMATE_PERCENT=50);
DMSQL executed successfully
used time: 12.930(ms). Execute id is 68.
SQL> 


#收集模式下对象的统计信息
SQL> call dbms_stats.gather_schema_stats(OWNNAME='CNDBA',DEGREE=3,ESTIMATE_PERCENT=50);
DMSQL executed successfully
used time: 983.111(ms). Execute id is 69.
SQL>

2.2.2 统计信息查看

#查看索引的统计信息
SQL> call dbms_stats.index_stats_show(OWNNAME='CNDBA',INDEXNAME='IDXID');

LINEID     BLEVEL      LEAF_BLOCKS          DISTINCT_KEYS        CLUSTERING_FACTOR NUM_ROWS             SAMPLE_SIZE         
---------- ----------- -------------------- -------------------- ----------------- -------------------- --------------------
1          1           16                   304                  0                 856                  304

used time: 23.888(ms). Execute id is 70.
SQL> 

#查看表的统计信息:
SQL>  call dbms_stats.table_stats_show(OWNNAME='CNDBA',TABNAME='EMPLOYEE');

LINEID     NUM_ROWS             LEAF_BLOCKS          LEAF_USED_BLOCKS    
---------- -------------------- -------------------- --------------------
1          856                  16                   12

used time: 0.953(ms). Execute id is 71.
SQL> 

#查看列的统计信息:
#注意示例是有2个结果集返回,disql 默认只显示一个,具体参考:
DM7 达梦数据库 disql 显示多个结果集的方法
https://www.cndba.cn/dave/article/3643

SQL> call dbms_stats.column_stats_show(OWNNAME='CNDBA',TABNAME='EMPLOYEE',COLNAME='EMPLOYEE_ID');

LINEID     NUM_DISTINCT         LOW_VALUE HIGH_VALUE NUM_NULLS            NUM_BUCKETS SAMPLE_SIZE          HISTOGRAM
---------- -------------------- --------- ---------- -------------------- ----------- -------------------- ---------
1          305                  1002      11144      0                    305         305                  FREQUENCY

used time: 36.771(ms). Execute id is 72.
SQL>

2.2.3 统计信息更新

#更新已有的统计信息,该过程没有参数
SQL> call dbms_stats. update_all_stats();
DMSQL executed successfully
used time: 377.859(ms). Execute id is 86.
SQL> 
`

2.2.4 统计信息删除

#删除列的统计信息。
SQL> call dbms_stats.delete_column_stats(OWNNAME='CNDBA',TABNAME='EMPLOYEE',COLNAME='EMPLOYEE_ID');
DMSQL executed successfully
used time: 4.009(ms). Execute id is 87.
SQL> call dbms_stats.column_stats_show(OWNNAME='CNDBA',TABNAME='EMPLOYEE',COLNAME='EMPLOYEE_ID');

LINEID     NUM_DISTINCT         LOW_VALUE HIGH_VALUE NUM_NULLS            NUM_BUCKETS SAMPLE_SIZE          HISTOGRAM
---------- -------------------- --------- ---------- -------------------- ----------- -------------------- ---------
1          NULL                 NULL      NULL       NULL                 NULL        NULL                 NULL

used time: 1.271(ms). Execute id is 88.
SQL> 

#删除与表相关对象的统计信息。
SQL> call dbms_stats.delete_table_stats(OWNNAME='CNDBA',TABNAME='EMPLOYEE');
DMSQL executed successfully
used time: 16.781(ms). Execute id is 89.
SQL> call dbms_stats.table_stats_show(OWNNAME='CNDBA',TABNAME='EMPLOYEE');

LINEID     NUM_ROWS             LEAF_BLOCKS          LEAF_USED_BLOCKS    
---------- -------------------- -------------------- --------------------
1          NULL                 NULL                 NULL

used time: 1.628(ms). Execute id is 90.
SQL> 

#删除模式下对象的统计信息。
SQL> call dbms_stats.delete_schema_stats(OWNNAME='CNDBA');
DMSQL executed successfully
used time: 46.016(ms). Execute id is 91.

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2297
    原创
  • 3
    翻译
  • 680
    转载
  • 200
    评论
  • 访问:10148243次
  • 积分:4578
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ