---
title: "分区表统计信息的收集与更新策略 - OceanBase 数据库 V4.5.0 | OceanBase 文档中心"
description: 分区表统计信息的收集与更新策略 在 OceanBase 数据库中，分区表的统计信息管理区分为 分区级统计信息 和 全局统计信息 ，这项统计信息机制仅适用于分区表。对于非分区表（即普通单表），仅存在单一的全局统计信息，不涉及分区统计或推导逻辑。 OceanBase 的分区表统计信息机制具有以下特点： 区分全局和分区统计…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.5.0

# 分区表统计信息的收集与更新策略

更新时间：2026-01-14 16:46:07

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.5.0/zh-CN/700.reference/1000.performance-tuning-guide/500.sql-optimization/400.sql-optimization/400.optimizer-statistics/350.strategies-for-partition-table-statistics.md)  

在 OceanBase 数据库中，分区表的统计信息管理区分为 **分区级统计信息** 和 **全局统计信息**，这项统计信息机制仅适用于分区表。对于非分区表（即普通单表），仅存在单一的全局统计信息，不涉及分区统计或推导逻辑。

OceanBase 的分区表统计信息机制具有以下特点：

1. **区分全局和分区统计**：两者独立存储，通过 `partition_id` 区分。
 2. **默认同时收集**：`APPROX_GLOBAL AND PARTITION` 粒度下会同时收集全局和分区统计。
 3. **自动检测缺失**：自动检测缺失或者过期的统计信息并触发收集。
 4. **基于分区统计推导全局统计**：根据分区统计的基础统计信息来推导全局基础统计信息，提高全局统计信息的时效和准确度。

本文详细说明 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` 包灵活调整过期阈值：

```sql
-- 设置全局默认值（影响所有新表）
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 模式），展示如何创建一个分区表、查看其统计信息的收集与自动更新行为，并演示全局统计信息如何通过分区统计推导生成。

### 步骤一：创建测试分区表

```sql
-- 创建数据库和用户（如尚未存在）
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')
);

```

### 步骤二：插入初始数据

```sql
-- 向各分区插入测试数据
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）

```sql
CALL DBMS_STATS.GATHER_TABLE_STATS(
    ownname => 'sales_db',
    tabname => 'sales',
    method_opt => 'FOR ALL COLUMNS SIZE AUTO',
    granularity => 'APPROX_GLOBAL AND PARTITION'
);

```

### 步骤四：查看统计信息

#### 查看全局表级统计信息

```sql
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;

```

**预期结果：**

```shell
+------------+-------------+----------+-------------+----------------------------+
| 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 列）

```sql
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';

```

**预期结果：**

```shell
+-------------+--------------+-----------+------------+-----------+-----------+
| 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 列）

```sql
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';

```

**预期结果：**

```shell
+----------------+-------------+--------------+-----------+------------+-----------+
| 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

```

### 步骤五：验证自动更新机制（可选）

```sql
-- 向 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;

```

**预期结果：**

```shell
+----------------+----------------------------+
| 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 过程参考文档如下：

- [MySQL 模式下 SET_GLOBAL_PREFS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004479834)
 - [MySQL 模式下 SET_SCHEMA_PREFS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004479823)
 - [MySQL 模式下 SET_TABLE_PREFS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004479847)
 - [Oracle 模式下 SET_GLOBAL_PREFS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004480212)
 - [Oracle 模式下 SET_SCHEMA_PREFS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004480173)
 - [Oracle 模式下 SET_TABLE_PREFS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004480198)

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
