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

3.X vs 4.X:OceanBase 手动收集统计信息的天壤之别!

237

作者:何文超,分享 MySQL 和 OceanBase 相关技术博文。 个人博客【CSDN | 雅俗数据库】

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 1200 字,预计阅读需要 5 分钟。


定档!2025 OceanBase 开发者大会,5 月 17 日广州见!


1. 手动收集统计信息的差异

1.1 不同版本在命令支持上的差异

如果需要显示收集某个表的统计信息,当前主流提供了两种方式来进行统计信息收集,分别是通过 DBMS_STATS
 系统包和 ANALYZE
 命令。

版本
MySQL 模式
Oracle 模式
3.X
仅支持 ANALYZE 命令方式
支持 DBMS_STATS 包和 ANALYZE 命令
4.X
支持 DBMS_STATS 包和 ANALYZE 命令
支持 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 不同版本下每日合并操作在收集统计信息上的差异

版本
统计信息收集方式
优势与不足
3.X
在每日合并时,系统自动收集统计信息
优势:自动化完成统计信息收集,操作便捷。
不足:每日合并为增量合并,统计信息难以持续精准;无法收集直方图信息,应对数据倾斜场景时缺乏有效手段。
4.X
将统计信息收集与每日合并进行解耦,每日合并期间不再负责收集统计信息
优势:优化架构设计,为解决之前统计信息收集的缺陷创造条件。
不足:有望提升统计信息准确性,更好地适应复杂数据场景。

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





带宽被 OBServer 备份 “榨干”,集群陷入 “无主” 危机
OBLogProxy 在 Binlog 模式下的故障案例解析
计算 OceanBase 可用 CPU 的核心逻辑


✨ Github:https://github.com/actiontech/sqle

📚 文档:https://actiontech.github.io/sqle-docs/

💻 官网:https://opensource.actionsky.com/sqle/

👥 微信群:请添加小助手加入 ActionOpenSource

🔗 商业支持:https://www.actionsky.com/sqle


文章转载自爱可生开源社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论