作者:何文超,分享 MySQL 和 OceanBase 相关技术博文。 个人博客【CSDN | 雅俗数据库】
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 1200 字,预计阅读需要 5 分钟。
定档!2025 OceanBase 开发者大会,5 月 17 日广州见!
如果需要显示收集某个表的统计信息,当前主流提供了两种方式来进行统计信息收集,分别是通过 DBMS_STATS
系统包和 ANALYZE
命令。
版本 | MySQL 模式 | Oracle 模式 |
---|---|---|
3.X | 仅支持 ANALYZE 命令方式 | 支持 DBMS_STATS 包和 ANALYZE 命令 |
4.X | 支持 DBMS_STATS 包和 ANALYZE 命令 | 支持 DBMS_STATS 包和 ANALYZE 命令 |
DBMS_STATS
系统包进行手动收集统计信息。DBMS_STATS
提供了更精细的控制,比如可以收集表级、Schema 级别的统计信息,还能设置不同的粒度、并行度等参数(如设置 degree
控制并行度、granularity
控制粒度等),能满足更复杂的业务场景需求。ANALYZE
命令进行手动收集统计信息。DBMS_STATS
包收集统计信息,若要使用类似 Oracle 模式的功能,需开启 enable_sql_extension
系统变量,但开启后也并非完全等同于 Oracle 模式的功能,且存在一定风险,不建议常规使用。版本 | 统计信息收集方式 | 优势与不足 |
---|---|---|
3.X | 在每日合并时,系统自动收集统计信息 | 优势:自动化完成统计信息收集,操作便捷。不足:每日合并为增量合并,统计信息难以持续精准;无法收集直方图信息,应对数据倾斜场景时缺乏有效手段。 |
4.X | 将统计信息收集与每日合并进行解耦,每日合并期间不再负责收集统计信息 | 优势:优化架构设计,为解决之前统计信息收集的缺陷创造条件。不足:有望提升统计信息准确性,更好地适应复杂数据场景。 |
注意:对于 OceanBase 3.x 的 MySQL 租户模式,不推荐使用 DBMS_STATS
方式收集统计信息。
-- 当表的数据量和列的个数较少(小于 1 千万条)
call dbms_stats.gather_table_stats('test', 't1');
-- 当表的数据量和列的个数较多(大于 1 千万条)
call dbms_stats.gather_table_stats(
'test',
't1',
degree=>8);
针对分区表收集统计信息时,可以增加收集的粒度和选择分区的方式来进行更精准的统计信息收集。
-- 增加收集的粒度和选择分区的方式
call dbms_stats.gather_table_stats(
'test',
't_part',
degree=>2,
granularity=>'APPROX_GLOBAL AND PARTITION');
除了对单个表进行统计信息收集,还可以对整个 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');
注意:对于 OceanBase 3.x 的 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;
SQL 适用于 OceanBase 4.2 及更高版本。
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);
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);
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有