首批通过分布式安全可靠测评,为关键业务系统打造
分区表统计信息的收集与更新策略
更新时间:2026-01-14 16:46:07
在 OceanBase 数据库中,分区表的统计信息管理区分为 分区级统计信息 和 全局统计信息,这项统计信息机制仅适用于分区表。对于非分区表(即普通单表),仅存在单一的全局统计信息,不涉及分区统计或推导逻辑。
OceanBase 的分区表统计信息机制具有以下特点:
- 区分全局和分区统计:两者独立存储,通过
partition_id区分。 - 默认同时收集:
APPROX_GLOBAL AND PARTITION粒度下会同时收集全局和分区统计。 - 自动检测缺失:自动检测缺失或者过期的统计信息并触发收集。
- 基于分区统计推导全局统计:根据分区统计的基础统计信息来推导全局基础统计信息,提高全局统计信息的时效和准确度。
本文详细说明 OceanBase 对分区表采用的统计信息收集策略、自动更新规则。
默认收集策略
OceanBase 对所有分区表默认采用 APPROX_GLOBAL AND PARTITION 粒度收集统计信息(通过 DBMS_STATS 包的 GATHER_INDEX_STATS 过程实现)。在此策略下,系统会同时生成两类统计:分区级统计信息 和 全局统计信息。
分区级统计信息
收集每个分区的独立统计信息:
- 基础统计:如列的最小值(min)、最大值(max)、不同值数量(NDV)等;
- 直方图:用于刻画数据分布特征。
全局统计信息
- 基础统计信息(min、max、不同值个数等):通过各分区的基础统计推导合成(例如:全局 min = 所有分区 min 的最小值);
- 全局直方图:无法根据分区的结果进行推导,需要对全表进行采样收集。
全局基础统计无需全表扫描,极大提升大规模分区表的统计收集效率,尤其适用于 TB/PB 级 AP 场景。
自动更新机制
为保障统计信息的时效性,OceanBase 内置自动检测与更新机制,基于数据变更比例触发刷新。
全局统计信息更新触发条件
以下任一情况将触发全局统计更新:
- 全局统计缺失:表中不存在全局统计信息。
- 全局数据过期:整表修改行数占比 ≥ 10%(由
STALE_PERCENT控制)。 - 任一分区统计过期:即使全局数据未变,只要某个分区统计失效,也会触发全局统计更新,以保证一致性。
更新过程:
- 全局基础统计:通过分区级统计信息推导出来(min、max、不同值个数等)。
- 全局直方图:需要单独收集,因为直方图目前无法根据分区的结果进行推导生成。
分区级统计信息更新触发条件
单个分区的统计在以下情况下更新:
- 该分区统计缺失:某个分区不存在统计信息。
- 该分区数据过期:本分区修改行数占比 ≥ 10%(由
STALE_PERCENT控制)。
更新过程:
- 重新收集过期分区的统计信息。
- 重新收集全局统计信息。
STALE_PERCENT 配置方法
用户可通过 DBMS_STATS 包灵活调整过期阈值:
-- 设置全局默认值(影响所有新表)
CALL dbms_stats.set_global_prefs('STALE_PERCENT', '50');
-- 设置 Schema 级别
CALL dbms_stats.set_schema_prefs('MY_SCHEMA', 'STALE_PERCENT', '30');
-- 设置表级别
CALL dbms_stats.set_table_prefs('MY_SCHEMA', 'MY_TABLE', 'STALE_PERCENT', '20');
自动检测能力
OceanBase 系统后台持续执行以下检测任务:
- 统计信息状态检查:扫描所有已存在的全局与分区统计信息。
- 过期分区检测:检查每个分区是否过期或缺失。
- 缺失统计检测:对缺失项自动标记并加入收集队列。
- 独立触发更新:支持全局与分区统计独立触发更新,互不影响。
关键参数
| 参数 | 默认值 | 说明 |
|---|---|---|
STALE_PERCENT |
10(10%) | 存储过程(set_schema_prefs、set_table_prefs)的参数,用于判断统计是否过期的变更阈值 |
| 默认收集粒度 | APPROX_GLOBAL AND PARTITION |
仅对分区表生效,非分区表使用 GLOBAL(通过 DBMS_STATS 包的 GATHER_INDEX_STATS 过程实现) |
与非分区表的对比
| 特性 | 分区表 | 非分区表(单表) |
|---|---|---|
| 统计类型 | 全局 + 分区 | 仅全局 |
| 全局基础统计来源 | 由分区统计推导 | 全表扫描生成 |
| 是否支持分区裁剪优化 | 是 | 否 |
| 默认收集粒度 | APPROX_GLOBAL AND PARTITION |
GLOBAL |
示例:OceanBase 分区表统计信息管理
该示例基于 OceanBase 数据库(MySQL 模式),展示如何创建一个分区表、查看其统计信息的收集与自动更新行为,并演示全局统计信息如何通过分区统计推导生成。
步骤一:创建测试分区表
-- 创建数据库和用户(如尚未存在)
CREATE DATABASE IF NOT EXISTS sales_db;
USE sales_db;
-- 创建按 RANGE 分区的销售记录表
CREATE TABLE sales (
id BIGINT NOT NULL,
region VARCHAR(50),
amount DECIMAL(10,2),
sale_date DATE,
PRIMARY KEY (id, sale_date)
) PARTITION BY RANGE COLUMNS(sale_date) (
PARTITION p2023_q1 VALUES LESS THAN ('2023-04-01'),
PARTITION p2023_q2 VALUES LESS THAN ('2023-07-01'),
PARTITION p2023_q3 VALUES LESS THAN ('2023-10-01'),
PARTITION p2023_q4 VALUES LESS THAN ('2024-01-01')
);
步骤二:插入初始数据
-- 向各分区插入测试数据
INSERT INTO sales VALUES
(1, 'North', 1500.00, '2023-01-15'),
(2, 'South', 2300.50, '2023-02-20'),
(3, 'East', 980.75, '2023-04-10'),
(4, 'West', 3200.00, '2023-06-25'),
(5, 'North', 1800.25, '2023-07-05'),
(6, 'South', 2100.00, '2023-09-18');
步骤三:收集统计信息(默认粒度:APPROX_GLOBAL AND PARTITION)
CALL DBMS_STATS.GATHER_TABLE_STATS(
ownname => 'sales_db',
tabname => 'sales',
method_opt => 'FOR ALL COLUMNS SIZE AUTO',
granularity => 'APPROX_GLOBAL AND PARTITION'
);
步骤四:查看统计信息
查看全局表级统计信息
SELECT
TABLE_NAME,
OBJECT_TYPE,
NUM_ROWS,
AVG_ROW_LEN,
LAST_ANALYZED
FROM oceanbase.DBA_TAB_STATISTICS
WHERE OWNER = 'SALES_DB' AND TABLE_NAME = 'SALES'
ORDER BY OBJECT_TYPE;
预期结果:
+------------+-------------+----------+-------------+----------------------------+
| TABLE_NAME | OBJECT_TYPE | NUM_ROWS | AVG_ROW_LEN | LAST_ANALYZED |
+------------+-------------+----------+-------------+----------------------------+
| sales | PARTITION | 2 | 73 | 2026-01-14 10:45:58.067339 |
| sales | PARTITION | 2 | 72 | 2026-01-14 10:45:58.067339 |
| sales | PARTITION | 2 | 73 | 2026-01-14 10:45:58.067339 |
| sales | PARTITION | 0 | 0 | 2026-01-14 10:45:58.067339 |
| sales | TABLE | 6 | 72 | 2026-01-14 10:45:58.079250 |
+------------+-------------+----------+-------------+----------------------------+
5 rows in set
查看全局列级统计信息(如 amount 列)
SELECT
COLUMN_NAME,
NUM_DISTINCT,
LOW_VALUE,
HIGH_VALUE,
NUM_NULLS,
HISTOGRAM
FROM oceanbase.DBA_TAB_COL_STATISTICS
WHERE OWNER = 'SALES_DB'
AND TABLE_NAME = 'SALES'
AND COLUMN_NAME = 'AMOUNT';
预期结果:
+-------------+--------------+-----------+------------+-----------+-----------+
| COLUMN_NAME | NUM_DISTINCT | LOW_VALUE | HIGH_VALUE | NUM_NULLS | HISTOGRAM |
+-------------+--------------+-----------+------------+-----------+-----------+
| amount | 6 | 980.75 | 3200.00 | 0 | NULL |
+-------------+--------------+-----------+------------+-----------+-----------+
1 row in set
查看分区级列统计信息(如 p2023_q1 分区的 amount 列)
SELECT
PARTITION_NAME,
COLUMN_NAME,
NUM_DISTINCT,
LOW_VALUE,
HIGH_VALUE,
NUM_NULLS
FROM oceanbase.DBA_PART_COL_STATISTICS
WHERE OWNER = 'SALES_DB'
AND TABLE_NAME = 'SALES'
AND PARTITION_NAME = 'P2023_Q1'
AND COLUMN_NAME = 'AMOUNT';
预期结果:
+----------------+-------------+--------------+-----------+------------+-----------+
| PARTITION_NAME | COLUMN_NAME | NUM_DISTINCT | LOW_VALUE | HIGH_VALUE | NUM_NULLS |
+----------------+-------------+--------------+-----------+------------+-----------+
| p2023_q1 | amount | 2 | 1500.00 | 2300.50 | 0 |
+----------------+-------------+--------------+-----------+------------+-----------+
1 row in set
步骤五:验证自动更新机制(可选)
-- 向 p2023_q4 插入新数据(模拟 >10% 变更)
INSERT INTO sales
SELECT 1000 + n, 'Central', ROUND(RAND()*5000, 2), '2023-11-01'
FROM (SELECT @n := @n + 1 AS n FROM information_schema.columns a, information_schema.columns b, (SELECT @n := 0) r LIMIT 50) t;
-- 等待后台自动检测(或手动触发)
CALL DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO();
-- 此时若变更比例 ≥ STALE_PERCENT(默认 10%),系统将自动标记为 stale 并可能触发收集
-- 再次查询 LAST_ANALYZED 时间是否更新
SELECT PARTITION_NAME, LAST_ANALYZED
FROM oceanbase.DBA_TAB_STATISTICS
WHERE OWNER = 'SALES_DB' AND TABLE_NAME = 'SALES'
ORDER BY PARTITION_NAME;
预期结果:
+----------------+----------------------------+
| PARTITION_NAME | LAST_ANALYZED |
+----------------+----------------------------+
| NULL | 2026-01-14 10:45:58.079250 |
| p2023_q1 | 2026-01-14 10:45:58.067339 |
| p2023_q2 | 2026-01-14 10:45:58.067339 |
| p2023_q3 | 2026-01-14 10:45:58.067339 |
| p2023_q4 | 2026-01-14 10:45:58.067339 |
+----------------+----------------------------+
5 rows in set
相关文档
相关 PL 过程参考文档如下: