暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

分布式数据库学习Note61:OceanBase社区版中,如何手动收集统计信息?

OceanBase 数据库优化器主要通过 DBMS_STATS 包 和 ANALYZE 语句两种方式手动收集统计信息。

通过 DBMS_STATS 包收集统计信息

OceanBase 数据库优化器支持利用 DBMS_STATS 包收集表级、Schema 级别的统计信息和索引统计信息,分别通过调用存储过程 gather_table_statsgather_schema_stats 和 gather_index_stats 来完成。

PROCEDURE gather_table_stats (
  ownname            VARCHAR2,
  tabname            VARCHAR2,
  partname           VARCHAR2 DEFAULT NULL,
  estimate_percent   NUMBER DEFAULT AUTO_SAMPLE_SIZE,
  block_sample       BOOLEAN DEFAULT FALSE,
  method_opt         VARCHAR2 DEFAULT DEFAULT_METHOD_OPT,
  degree             NUMBER DEFAULT NULL,
  granularity        VARCHAR2 DEFAULT DEFAULT_GRANULARITY,
  cascade            BOOLEAN DEFAULT NULL,
  stattab            VARCHAR2 DEFAULT NULL,
  statid             VARCHAR2 DEFAULT NULL,
  statown            VARCHAR2 DEFAULT NULL,
  no_invalidate      BOOLEAN DEFAULT FALSE,
  stattype           VARCHAR2 DEFAULT 'DATA',
  force              BOOLEAN DEFAULT FALSE
);

PROCEDURE gather_schema_stats (
  ownname            VARCHAR2,
  estimate_percent   NUMBER DEFAULT AUTO_SAMPLE_SIZE,
  block_sample       BOOLEAN DEFAULT FALSE,
  method_opt         VARCHAR2 DEFAULT DEFAULT_METHOD_OPT,
  degree             NUMBER DEFAULT NULL,
  granularity        VARCHAR2 DEFAULT DEFAULT_GRANULARITY,
  cascade            BOOLEAN DEFAULT NULL,
  stattab            VARCHAR2 DEFAULT NULL,
  statid             VARCHAR2 DEFAULT NULL,
  statown            VARCHAR2 DEFAULT NULL,
  no_invalidate      BOOLEAN DEFAULT FALSE,
  stattype           VARCHAR2 DEFAULT 'DATA',
  force              BOOLEAN DEFAULT FALSE
);

PROCEDURE gather_index_stats (
  ownname            VARCHAR2,
  indname            VARCHAR2,
  partname           VARCHAR2 DEFAULT NULL,
  estimate_percent   NUMBER DEFAULT AUTO_SAMPLE_SIZE,
  stattab            VARCHAR2 DEFAULT NULL,
  statid             VARCHAR2 DEFAULT NULL,
  statown            VARCHAR2 DEFAULT NULL,
  degree             NUMBER DEFAULT NULL,
  granularity        VARCHAR2 DEFAULT DEFAULT_GRANULARITY,
  no_invalidate      BOOLEAN DEFAULT FALSE,
  force              BOOLEAN DEFAULT FALSE,
  tabname            VARCHAR2  DEFAULT NULL
);

参数解释如下表所示。

参数解释
ownname表所在数据库名称。
tabname表名。
indname索引名。
partname分区名。默认为 NULL
estimate_percent指定使用多少比例的数据计算其分布特征,范围为 [0.000001,100]。 如果指定为 NULL,则使用所有数据。默认是 AUTO_SAMPLE_SIZE,即由优化器内部决定使用多少比例的数据。
block_sample是否使用块采样代替行采样,默认为 FALSE
method_opt设置列级别的统计信息收集方式。详细信息,请参见 method_opt
degree统计信息收集时的并行度,默认为 NULL
granularity统计信息收集时的分区粒度。 目前支持以下几种设置:
  • 'GLOBAL':收集全局级别的统计信息。
  • 'PARTITION':收集分区级别的统计信息。
  • 'SUBPARTITION':收集子分区级别的统计信息。
  • 'ALL' :收集所有级别的统计信息(包括 GLOBALPARTITION 和 SUBPARTITION 级别)。
  • 'AUTO' :使用默认方式收集所有级别的统计信息(包括 GLOBALPARTITION 和 SUBPARTITION 级别)。不设置 granularity 时,'AUTO' 为默认值。
  • 'DEFAULT':收集 GLOBAL 和 PATITION 级别的统计信息。
  • 'GLOBAL AND PARTITION':收集 GLOBAL 和 PATITION 级别的统计信息。
  • 'APPROX_GLOBAL AND PARTITION':收集分区级别的统计信息,并根据分区信息推导出全局级别的统计信息。
cascade是否同时收集表的索引统计信息,默认为 TRUE
stattab该参数暂未实现,不可用。
statid该参数暂未实现,不可用。
statown该参数暂未实现,不可用。
no_invalidate该参数暂未实现,不可用。
stattype该参数暂未实现,不可用。
force是否强制收集信息,并忽略锁的状态,默认为 FALSE

method_opt

method_opt 主要采用下面的语法方式来设定:

method_opt:
  FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause]
| FOR COLUMNS [size clause] column [size_clause] [,column [size_clause]...]

size_clause:
  SIZE integer 
| SIZE REPEAT
| SIZE AUTO
| SIZE SKEWONLY

column:
   column_name
| (column_name [, column_name])

参数解释如下表所示。

参数解释
SIZE integer指定收集列的直方图桶的个数,取值范围为 [1, 2048]。
REPEAT仅仅只收集被收集过直方图的列的直方图。使用之前收集直方图设置的桶个数。
AUTOOceanBase 数据库优化器根据列的使用情况,来决定是否收集列的直方图。直方图桶个数使用默认值 254。
SKEWONLY仅仅只收集数据分布不均匀的列的直方图。直方图桶个数使用默认值 254。

此外,DBMS_STATS 包还提供了 GATHER_DATABASE_STATS_JOB_PROC 来收集整个数据库所有表的统计信息,所有收集策略都会采用默认配置的 Prefs,关于设置 Prefs 的详细信息,请参见 收集策略配置项(Prefs)管理功能

PROCEDURE GATHER_DATABASE_STATS_JOB_PROC();

示例

DBMS_STATS 包收集统计信息的相关示例如下:

  • 收集用户 user 的表 tbl1 的全局级别的统计信息,所有列的桶个数设定为 128。

    CALL dbms_stats.gather_table_stats('user', 'tbl1', granularity=>'GLOBAL', method_opt=>'FOR ALL COLUMNS SIZE 128');
    
  • 收集用户 user 的表 t_part1 的分区级别的统计信息,并行度为 64,只收集数据分布不均匀的列的直方图。

    CALL dbms_stats.gather_table_stats('user', 't_part1', degree=>'64', granularity=>'PARTITION', method_opt=>'FOR ALL COLUMNS SIZE SKEWONLY');
    
  • 收集用户 user 的表 t_subpart1 所有的统计信息,并行度为 128,只收集 50% 的数据,所有的列的直方图都由优化器内部决定。

    CALL dbms_stats.gather_table_stats('user', 't_subpart1', degree=>'128', estimate_percent=> '50', granularity=>'ALL', method_opt=>'FOR ALL COLUMNS SIZE AUTO');
    

表级和索引统计信息收集策略 GRANULARITY 的关联

默认情况下,在收集表统计信息的同时也会收集表上所有索引统计信息,由于索引表上的部分统计信息是可以通过基表的统计信息得到的,包括行数、平均行长(通过对应的几个列计算)等,因此可以加速统计信息的获取,也可以避免二次扫描全表数据。对于本地索引和全局索引两者在 GRANULARITY 上有所区别,如下表所示。

指定分区GRANULARITY全局索引本地索引
ALLGLOBAL 级别ALL
AUTOGLOBAL 级别AUTO
DEFAULTGLOBAL 级别DEFAULT
GLOBAL AND PARTITIONGLOBAL 级别GLOBAL AND PARTITION
APPROX_GLOBAL AND PARTITIONGLOBAL 级别APPROX_GLOBAL AND PARTITION
GLOBALGLOBAL 级别GLOBAL
PARTITIONGLOBAL 级别PARTITION
SUBPARTITION不收集SUBPARTITION
ALLGLOBAL 级别ALL
AUTOGLOBAL 级别AUTO
DEFAULTGLOBAL 级别DEFAULT
GLOBAL AND PARTITIONGLOBAL 级别GLOBAL AND PARTITION
APPROX_GLOBAL AND PARTITION不收集APPROX_GLOBAL AND PARTITION
GLOBALGLOBAL 级别GLOBAL
PARTITION不收集PARTITION
SUBPARTITION不收集SUBPARTITION

通过 ANALYZE 语句收集统计信息

ANALYZE 语法如下:

analyze_stmt:
ANALYZE TABLE table_name UPDATE HISTOGRAM ON column_name_list WITH INTNUM BUCKETS

当 Session 变量 enable_sql_extension 为 TRUE 的时候,可以使用 Oracle 模式的语法,即 OceanBase 数据库为 MySQL 模式提供的扩展语法。

analyze_stmt:
ANALYZE TABLE table_name [use_partition] analyze_statistics_clause

ANALYZE 语句统计信息收集示例如下:

  • 收集表 tbl1 的统计信息,列的桶个数为 30 个。

    ANALYZE TABLE tbl1 UPDATE HISTOGRAM ON a, b, c, d WITH 30 BUCKETS;
    
  • 在 MySQL 模式下使用 Oracle 模式的语法收集用户 test 的表 tbl1 的统计信息,所有列的桶个数设定为 128。

    ALTER SYSTEM SET ENABLE_SQL_EXTENSION = TRUE;
    ANALYZE TABLE tbl1 COMPUTE STATISTICS FOR ALL COLUMNS SIZE 128;
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论