
作者:何文超,分享 MySQL 和 OceanBase 相关技术博文。 个人博客【CSDN | 雅俗数据库】
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 1200 字,预计阅读需要 5 分钟。
定档!2025 OceanBase 开发者大会,5 月 17 日广州见!

1. 手动收集统计信息的差异
1.1 不同版本在命令支持上的差异
如果需要显示收集某个表的统计信息,当前主流提供了两种方式来进行统计信息收集,分别是通过 DBMS_STATS
系统包和 ANALYZE
命令。
Oracle 模式
推荐使用 DBMS_STATS
系统包进行手动收集统计信息。原因是 DBMS_STATS
提供了更精细的控制,比如可以收集表级、Schema 级别的统计信息,还能设置不同的粒度、并行度等参数(如设置degree
控制并行度、granularity
控制粒度等),能满足更复杂的业务场景需求。
MySQL 模式
3.x 版本推荐使用 ANALYZE
命令进行手动收集统计信息。因为 3.x 版本的 MySQL 模式下不支持 DBMS_STATS
包收集统计信息,若要使用类似 Oracle 模式的功能,需开启enable_sql_extension
系统变量,但开启后也并非完全等同于 Oracle 模式的功能,且存在一定风险,不建议常规使用。
1.2 不同版本下每日合并操作在收集统计信息上的差异
不足:每日合并为增量合并,统计信息难以持续精准;无法收集直方图信息,应对数据倾斜场景时缺乏有效手段。 | ||
不足:有望提升统计信息准确性,更好地适应复杂数据场景。 |
2. DBMS_STATS 方式
注意:对于 OceanBase 3.x 的 MySQL 租户模式,不推荐使用 DBMS_STATS
方式收集统计信息。
2.1 表级统计信息收集
2.1.1 非分区表的统计信息收集
-- 当表的数据量和列的个数较少(小于 1 千万条)
call dbms_stats.gather_table_stats('test', 't1');
-- 当表的数据量和列的个数较多(大于 1 千万条)
call dbms_stats.gather_table_stats(
'test',
't1',
degree=>8);
2.1.2 分区表的统计信息收集
针对分区表收集统计信息时,可以增加收集的粒度和选择分区的方式来进行更精准的统计信息收集。
-- 增加收集的粒度和选择分区的方式
call dbms_stats.gather_table_stats(
'test',
't_part',
degree=>2,
granularity=>'APPROX_GLOBAL AND PARTITION');
2.2 schema 级别的统计信息收集
除了对单个表进行统计信息收集,还可以对整个 schema
下的对象进行统计信息收集。这在批量处理多个相关表的统计信息时非常有用。
-- 对 TEST schema下所有对象收集统计信息
call dbms_stats.gather_schema_stats('TEST');
-- 对 TEST schema下所有对象收集统计信息,并设置并行度为 16
call dbms_stats.gather_schema_stats('TEST', degree=>'16');
-- 对 TEST schema 下 big_table 表收集统计信息,设置并行度为 128,指定列统计信息的粒度为1
call dbms_stats.gather_table_stats(
'test',
'big_table',
degree=>128,
method_opt=>'for all columns size 1');
-- 锁定 test schema 下 big_table 表的统计信息
call dbms_stats.lock_table_stats('test','big_table');
-- 再次对 TEST schema下所有对象收集统计信息,设置并行度为 16,指定列统计信息的粒度为 1
call dbms_stats.gather_schema_stats(
'TEST',
degree=>'16',
method_opt=>'for all columns size 1');
-- 解锁 test schema 下 big_table 表的统计信息
call dbms_stats.unlock_table_stats('test','big_table');
3. ANALYZE 方式
注意:对于 OceanBase 3.x 的 MySQL 租户模式,推荐使用 ANALYZE
方式收集统计信息。
3.1 MySQL 模式下 ANALYZE 语法
-- MySQL 模式下 ANALYZE 语句用法
ANALYZE TABLE table_name UPDATE HISTOGRAM ON column_name_list WITH INTNUM BUCKETS
-- 示例如下
ANALYZE TABLE sbtest1 UPDATE HISTOGRAM ON id,k,c,pad WITH 30 BUCKETS;
在 MySQL 模式下,如果不想显式写出全部字段,可以通过 FOR ALL COLUMNS
子句来收集表中所有列的统计信息。
但需要注意的是, FOR ALL COLUMNS
是 Oracle 模式下的语法,因此需要先启用 enable_sql_extension
系统变量以支持 Oracle 模式的扩展语法。
以下是具体的命令示例:
ALTER SYSTEM SET enable_sql_extension = TRUE;
ANALYZE TABLE products COMPUTE STATISTICS FOR ALL COLUMNS SIZE 30;
4、统计信息的检查
SQL 适用于 OceanBase 4.2 及更高版本。
MySQL 模式
select distinct DATABASE_NAME, TABLE_NAME
from oceanbase.DBA_OB_TABLE_STAT_STALE_INFO
where DATABASE_NAME not in('oceanbase','mysql', '__recyclebin')
and (IS_STALE = 'YES' or LAST_ANALYZED_TIME is null);
Oracle 模式
select distinct OWNER, TABLE_NAME
from sys.DBA_OB_TABLE_STAT_STALE_INFO
where OWNER != 'oceanbase'
and OWNER != '__recyclebin' and (IS_STALE = 'YES' or LAST_ANALYZED_TIME is null);
定档!2025 OceanBase 开发者大会,5 月 17 日广州见!

本文关键字:#OceanBase


✨ Github:https://github.com/actiontech/sqle
📚 文档:https://actiontech.github.io/sqle-docs/
💻 官网:https://opensource.actionsky.com/sqle/
👥 微信群:请添加小助手加入 ActionOpenSource
🔗 商业支持:https://www.actionsky.com/sqle





