---
title: "手动收集统计信息 - OceanBase 数据库 V4.6.0 | OceanBase 文档中心"
description: 手动收集统计信息 OceanBase 数据库优化器主要通过 DBMS_STATS 包 和 ANALYZE 语句两种方式手动收集统计信息。 说明 OceanBase 数据库当前不支持对统计信息收集时间的预估。因此建议将 ob_query_timeout 设置得足够长，以便完成统计信息的收集。特别是在收集 schema …
---
切换语言

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

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

# 手动收集统计信息

更新时间：2026-06-14 11:27:37

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.6.0/zh-CN/700.reference/1000.performance-tuning-guide/500.sql-optimization/400.sql-optimization/400.optimizer-statistics/200.statistics-collection-methods/300.collect-statistics-manually.md)  

OceanBase 数据库优化器主要通过 `DBMS_STATS` 包 和 `ANALYZE` 语句两种方式手动收集统计信息。

#### 说明

OceanBase 数据库当前不支持对统计信息收集时间的预估。因此建议将 [ob_query_timeout](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005685237) 设置得足够长，以便完成统计信息的收集。特别是在收集 schema 级别的统计信息时，如果由于超时而中断，已经收集完毕的统计信息将被保留。

## 使用说明与限制

- 推荐用户在会话（Session）级别调大 [ob_query_timeout](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005685237) 变量，这样做仅影响当前会话，不会干扰其他操作。

## 完整步骤

| 阶段 | 操作 | 命令/视图 |
| --- | --- | --- |
| **准备** | 调大 `ob_query_timeout` | `SET SESSION ob_query_timeout = 36000000000;` |
| **执行** | 调用 `DBMS_STATS` 或 `ANALYZE` | `CALL dbms_stats.gather_table_stats(...);` |
| **监控** | 查看收集进度与状态 | `(G)V$OB_OPT_STAT_GATHER_MONITOR` |
| **验证** | 检查统计信息是否写入/是否过期 | [`DBA_TAB_STATISTICS`](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005683850)、[`DBA_TAB_COL_STATISTICS`](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005683587)（以及直方图相关视图） |
| **诊断** | 处理失败或异常 | [`DBA_OB_TASK_OPT_STAT_GATHER_HISTORY`](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005683724)、[`DBA_OB_TABLE_OPT_STAT_GATHER_HISTORY`](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005683885) + [执行计划缓存（Plan Cache）](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005685088)（含刷新/淘汰说明） |

## 通过 DBMS_STATS 包收集统计信息

OceanBase 数据库优化器支持利用 [DBMS_STATS (MySQL 模式)](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686401)/[DBMS_STATS (Oracle 模式)](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686752) 包收集表级、Schema 级别的统计信息和索引统计信息，分别通过调用存储过程 `gather_table_stats`、`gather_schema_stats` 和 `gather_index_stats` 来完成。

    MySQL mode   Oracle mode

```sql
PROCEDURE gather_table_stats (
  ownname            VARCHAR2,
  tabname            VARCHAR2,
  partname           VARCHAR2 DEFAULT NULL,
  estimate_percent   NUMBER DEFAULT AUTO_SAMPLE_SIZE,
  block_sample       BOOLEAN DEFAULT FALSE,
  method_opt         VARCHAR2 DEFAULT DEFAULT_METHOD_OPT,
  degree             NUMBER DEFAULT NULL,
  granularity        VARCHAR2 DEFAULT DEFAULT_GRANULARITY,
  cascade            BOOLEAN DEFAULT NULL,
  stattab            VARCHAR2 DEFAULT NULL,
  statid             VARCHAR2 DEFAULT NULL,
  statown            VARCHAR2 DEFAULT NULL,
  no_invalidate      BOOLEAN DEFAULT FALSE,
  stattype           VARCHAR2 DEFAULT 'DATA',
  force              BOOLEAN DEFAULT FALSE
);

PROCEDURE gather_schema_stats (
  ownname            VARCHAR2,
  estimate_percent   NUMBER DEFAULT AUTO_SAMPLE_SIZE,
  block_sample       BOOLEAN DEFAULT FALSE,
  method_opt         VARCHAR2 DEFAULT DEFAULT_METHOD_OPT,
  degree             NUMBER DEFAULT NULL,
  granularity        VARCHAR2 DEFAULT DEFAULT_GRANULARITY,
  cascade            BOOLEAN DEFAULT NULL,
  stattab            VARCHAR2 DEFAULT NULL,
  statid             VARCHAR2 DEFAULT NULL,
  statown            VARCHAR2 DEFAULT NULL,
  no_invalidate      BOOLEAN DEFAULT FALSE,
  stattype           VARCHAR2 DEFAULT 'DATA',
  force              BOOLEAN DEFAULT FALSE
);

PROCEDURE gather_index_stats (
  ownname            VARCHAR2,
  indname            VARCHAR2,
  partname           VARCHAR2 DEFAULT NULL,
  estimate_percent   NUMBER DEFAULT AUTO_SAMPLE_SIZE,
  stattab            VARCHAR2 DEFAULT NULL,
  statid             VARCHAR2 DEFAULT NULL,
  statown            VARCHAR2 DEFAULT NULL,
  degree             NUMBER DEFAULT NULL,
  granularity        VARCHAR2 DEFAULT DEFAULT_GRANULARITY,
  no_invalidate      BOOLEAN DEFAULT FALSE,
  force              BOOLEAN DEFAULT FALSE,
  tabname            VARCHAR2  DEFAULT NULL
);

```

```sql
DBMS_STATS.GATHER_TABLE_STATS (
ownname             VARCHAR2,
tabname             VARCHAR2,
partname            VARCHAR2 DEFAULT NULL,
estimate_percent    NUMBER DEFAULT AUTO_SAMPLE_SIZE,
block_sample        BOOLEAN  DEFAULT FALSE,
method_opt          VARCHAR2 DEFAULT DEFAULT_METHOD_OPT,
degree              NUMBER   DEFAULT to_degree_type(get_param('DEGREE')),
granularity         VARCHAR2 DEFAULT DEFAULT_GRANULARITY,
cascade             BOOLEAN DEFAULT NULL,
no_invalidate       BOOLEAN DEFAULT FALSE,
stattype            VARCHAR2 DEFAULT 'DATA',
force               BOOLEAN DEFAULT FALSE,
hist_est_percent    NUMBER DEFAULT AUTO_SAMPLE_SIZE,
hist_block_sample   BOOLEAN DEFAULT NULL
);

DBMS_STATS.GATHER_SCHEMA_STATS (
ownname            VARCHAR2,
estimate_percent   NUMBER DEFAULT AUTO_SAMPLE_SIZE,
block_sample       BOOLEAN DEFAULT FALSE,
method_opt         VARCHAR2 DEFAULT DEFAULT_METHOD_OPT,
degree             NUMBER DEFAULT NULL,
granularity        VARCHAR2 DEFAULT DEFAULT_GRANULARITY,
cascade            BOOLEAN DEFAULT NULL,
no_invalidate      BOOLEAN DEFAULT FALSE,
stattype           VARCHAR2 DEFAULT 'DATA',
force              BOOLEAN DEFAULT FALSE);

DBMS_STATS.GATHER_INDEX_STATS (
ownname            VARCHAR2,
indname            VARCHAR2,
partname           VARCHAR2 DEFAULT NULL,
estimate_percent   NUMBER DEFAULT AUTO_SAMPLE_SIZE,
stattab            VARCHAR2 DEFAULT NULL,
statown            VARCHAR2 DEFAULT NULL,
degree             NUMBER DEFAULT NULL,
granularity        VARCHAR2 DEFAULT DEFAULT_GRANULARITY,
no_invalidate      BOOLEAN DEFAULT FALSE,
force              BOOLEAN DEFAULT FALSE,
tabname            VARCHAR2 DEFAULT NULL);

```

详细的参数解释您可以参考：

- [GATHER_TABLE_STATS (MySQL 模式)](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686399)/[GATHER_TABLE_STATS (Oracle 模式)](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686780)
 - [GATHER_SCHEMA_STATS (MySQL 模式)](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686388)/[GATHER_SCHEMA_STATS (Oracle 模式)](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686753)
 - [GATHER_INDEX_STATS (MySQL 模式)](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686392)/[GATHER_INDEX_STATS (Oracle 模式)](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686759)

`DBMS_STATS` 包提供的收集策略会采用默认配置的 Prefs，关于设置 Prefs 的详细信息，请参见 [收集策略配置项（Prefs）管理功能](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005687668)。

```sql
PROCEDURE GATHER_DATABASE_STATS_JOB_PROC();

```

### 示例

`DBMS_STATS` 包收集统计信息的相关示例如下：

- 收集用户 `user` 的表 `tbl1` 的全局级别的统计信息。

  ```sql
  CALL dbms_stats.gather_table_stats('user', 'tbl1', granularity=>'GLOBAL', method_opt=>'FOR ALL COLUMNS SIZE AUTO');

  ```
 - 收集用户 `user` 的表 `t_part1` 的分区级别的统计信息，并行度为 64，只收集数据分布不均匀的列的直方图。

  ```sql
  CALL dbms_stats.gather_table_stats('user', 't_part1', degree=>'64', granularity=>'PARTITION', method_opt=>'FOR ALL COLUMNS SIZE SKEWONLY');

  ```
 - 收集用户 `user` 的表 `t_subpart1` 所有的统计信息，并行度为 128，只收集 50% 的数据，所有的列的直方图都由优化器内部决定。

  ```sql
  CALL dbms_stats.gather_table_stats('user', 't_subpart1', degree=>'128', estimate_percent=> '50', granularity=>'ALL', method_opt=>'FOR ALL COLUMNS SIZE AUTO');

  ```

执行 `gather_table_stats` 后，立即查询 `(G)V$OB_OPT_STAT_GATHER_MONITOR` 可确认任务是否启动。

### 表级和索引统计信息收集策略 GRANULARITY 的关联

默认情况下，在收集表统计信息的同时也会收集表上所有索引统计信息，由于索引表上的部分统计信息是可以通过基表的统计信息得到的，包括行数、平均行长（通过对应的几个列计算）等，因此可以加速统计信息的获取，也可以避免二次扫描全表数据。对于本地索引和全局索引两者在 `GRANULARITY` 上有所区别，如下表所示。

| 指定分区 | GRANULARITY | 全局索引 | 本地索引 |
| --- | --- | --- | --- |
| 否 | ALL | GLOBAL 级别 | ALL |
| 否 | AUTO | GLOBAL 级别 | AUTO |
| 否 | DEFAULT | GLOBAL 级别 | DEFAULT |
| 否 | GLOBAL AND PARTITION | GLOBAL 级别 | GLOBAL AND PARTITION |
| 否 | APPROX_GLOBAL AND PARTITION | GLOBAL 级别 | APPROX_GLOBAL AND PARTITION |
| 否 | GLOBAL | GLOBAL 级别 | GLOBAL |
| 否 | PARTITION | GLOBAL 级别 | PARTITION |
| 否 | SUBPARTITION | 不收集 | SUBPARTITION |
| 是 | ALL | GLOBAL 级别 | ALL |
| 是 | AUTO | GLOBAL 级别 | AUTO |
| 是 | DEFAULT | GLOBAL 级别 | DEFAULT |
| 是 | GLOBAL AND PARTITION | GLOBAL 级别 | GLOBAL AND PARTITION |
| 是 | APPROX_GLOBAL AND PARTITION | 不收集 | APPROX_GLOBAL AND PARTITION |
| 是 | GLOBAL | GLOBAL 级别 | GLOBAL |
| 是 | PARTITION | 不收集 | PARTITION |
| 是 | SUBPARTITION | 不收集 | SUBPARTITION |

## 通过 ANALYZE 语句收集统计信息

在 Oracle 模式和 MySQL 模式下，OceanBase 数据库支持使用 `ANALYZE` 语句进行统计信息的收集。

MySQL 模式下的 `ANALYZE` 语法如下：

```sql
analyze_stmt:
ANALYZE TABLE table_name UPDATE HISTOGRAM ON column_name_list WITH INTNUM BUCKETS

```

当租户级配置项 `enable_sql_extension` 为 `TRUE` 的时候，可以使用 Oracle 模式的语法，即 OceanBase 数据库为 MySQL 模式提供的扩展语法。

```sql
analyze_stmt:
ANALYZE TABLE table_name [use_partition] analyze_statistics_clause

```

MySQL 模式下 `ANALYZE` 语句统计信息收集示例如下：

- 收集表 `tbl1` 的统计信息，列的桶个数为 30 个。

  ```sql
  ANALYZE TABLE tbl1 UPDATE HISTOGRAM ON a, b, c, d WITH 30 BUCKETS;

  ```
 - 在 MySQL 模式下使用 Oracle 模式的语法收集用户 `test` 的表 `tbl1` 的统计信息。

  ```sql
  ALTER SYSTEM SET ENABLE_SQL_EXTENSION = TRUE;
  ANALYZE TABLE tbl1 COMPUTE STATISTICS FOR ALL COLUMNS SIZE AUTO;

  ```

Oracle 模式下的 `ANALYZE` 语法如下：

use_partition:
  PARTITION (parition_name [,partition_name...])
| SUBPARTITION(subpartition_name [,subpartition_name...])

analyze_statistics_clause:
  COMPUTE STATISTICS [analyze_for_clause]
| ESTIMATE STATISTICS [analyze_for_clause] [SAMPLE INTNUM {ROWS | PERCENTAGE}]

analyze_for_clause:
  FOR TABLE
| FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause]
| FOR COLUMNS [size_clause] column [size_clause] [,column [size_clause]...]

size_clause:
  SIZE integer
| SIZE REPEAT
| SIZE AUTO
| SIZE SKEWONLY

column:
  column_name
| (column_name [,column_name])

```

上述语法中，指定列的统计信息直方图收集方式和 DBMS_STATS 包的 `method_opt` 语法相同，请参见 **method_opt**。

与 DBMS_STATS 包收集统计信息的方式相比，`ANALYZE` 语句并没有提供那么丰富的策略设置。为了支持 `ANALYZE` 语句只收集 `GLOBAL` 级别的统计信息，约定规则是只需要在 `use_partition` 语法中设置 `partition_name` 为表名即可。

Oracle 模式下 `ANALYZE` 语句统计信息收集示例如下：

- 收集用户 `user` 的表 `tbl1` 的统计信息。

  ```sql
  ANALYZE TABLE tbl1 COMPUTE STATISTICS FOR ALL COLUMNS SIZE AUTO;

  ```
 - 收集用户 `user` 的表 `t_part1` 的 `GLOBAL` 级别的统计信息，并且只收集数据分布不均匀的列的直方图。

  ```sql
  ANALYZE TABLE t_part1 PARTITION (t_part1) COMPUTE STATISTICS FOR ALL COLUMNS SIZE SKEWONLY;

  ```
 - 收集用户 `user` 的表 `t_subpart1` 的分区 `p0sp0` 和 `p1sp2` 的统计信息，所有的列的直方图都由优化器内部决定。

  ```sql
  ANALYZE TABLE t_subpart1 SUBPARTITION(p0sp0,p1sp2) COMPUTE STATISTICS FOR ALL COLUMNS SIZE AUTO;

  ```

## 手动统计信息收集的实践场景

### 非分区表的统计信息收集

当表的数据量和列的个数的乘积不高于一千万时，推荐使用如下命令收集非分区表的统计信息。如下示例中表 `test.t1` 有 10 个列，同时数据量在一百万行。

```sql
CREATE TABLE test.t1(c1 INT, c2 INT, c3 INT, c4 INT, c5 INT, c6 INT, c7 INT, c8 INT, c9 INT, c10 INT);
CREATE TABLE t2 (c1 INT PRIMARY KEY);
INSERT INTO t2 VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT /*+APPEND*/ INTO t1 SELECT * FROM (SELECT s0.c1 c1, s1.c1 c2, s2.c1 c3, s3.c1 c4, s4.c1 c5, s5.c1 c6, s0.c1 * 10 c7, s1.c1 * 10 c8, s2.c1 * 10 c9, s3.c1 * 10 c10 FROM t2 s0, t2 s1, t2 s2, t2 s3, t2 s4, t2 s5);

# 不收集直方图的场景
CALL DBMS_STATS.GATHER_TABLE_STATS('test', 't1', method_opt=>'for all columns size 1');

# 收集直方图的场景并使用默认策略
CALL DBMS_STATS.GATHER_TABLE_STATS('test', 't1');

```

当表的数据量和列的个数的乘积超过一千万时，推荐根据数据业务情况和系统资源设置一定并行度来加快统计信息的收集。如下示例中表 `test.t1` 中的数据量增大到一千万行，使用 8 个并行度。

```sql
# 不收集直方图的场景
CALL DBMS_STATS.GATHER_TABLE_STATS('test', 't1', degree=>8, method_opt=>'for all columns size 1');

# 收集直方图的场景并使用默认策略
CALL DBMS_STATS.GATHER_TABLE_STATS('test', 't1', degree=>8);

```

### 分区表的统计信息收集

相比较于非分区表，分区表的统计信息收集策略需要考虑分区统计信息收集。在系统资源允许的情况下，对于分区表的统计信息收集策略，推荐将收集非分区表的并行度再额外增加一倍。

如下示例中，相同场景的 `test.t_part` 表有 10 个列，同时数据量在一百万行。由于增加了分区统计信息的收集，因此并行度增加为 2。

```sql
CREATE TABLE t_part(c1 INT, c2 INT, c3 INT, c4 INT, c5 INT, c6 INT, c7 INT, c8 INT, c9 INT, c10 INT) PARTITION BY HASH(c1) PARTITIONS 128;
CREATE TABLE t2 (c1 INT PRIMARY KEY);
INSERT INTO t2 VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT /*+APPEND*/ INTO t_part SELECT * FROM (SELECT s0.c1 c1, s1.c1 c2, s2.c1 c3, s3.c1 c4, s4.c1 c5, s5.c1 c6, s0.c1 * 10 c7, s1.c1 * 10 c8, s2.c1 * 10 c9, s3.c1 * 10 c10 FROM t2 s0, t2 s1, t2 s2, t2 s3, t2 s4, t2 s5);

```

针对分区表，除了上述增加并行度以外，也可以考虑分区推导方式的收集，即收集分区的统计信息，进而通过分区统计信息推导全局统计信息，以加快收集的效率。例如同样的场景，不增加并行度，而是调整收集的分区方式，示例如下。

```sql
# 不收集直方图的场景
CALL DBMS_STATS.GATHER_TABLE_STATS('test', 't_part', granularity=>'APPROX_GLOBAL AND PARTITION', method_opt=>'for all columns size 1');

# 收集直方图的场景并使用默认策略
CALL DBMS_STATS.GATHER_TABLE_STATS('test', 't_part', granularity=>'APPROX_GLOBAL AND PARTITION');

```

更多关于分区表统计信息的收集与更新策略，以及详细示例 参见[分区表统计信息的收集与更新策略](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686956)。

### Schema（数据库）级别的统计信息收集

除了手动的对单表的统计信息收集以外，OceanBase 数据库 `DBMS_STATS` 系统包还提供了对整个用户下的所有表进行统计信息收集。

#### 说明

该功能仅在 OceanBase 数据库 V4.x 版本的双模式和 OceanBase 数据库 V3.2.x 版本的 Oracle 模式下支持。

由于收集某个用户下的所有表统计信息比较耗时，因此，建议在业务低峰期使用该功能。

如果该用户下所有表的数据量都是一些小表（数据量不超过一百万行），可以直接使用如下示例中收集 `test` 用户的统计信息命令。

```sql
# 不收集直方图的场景
CALL DBMS_STATS.GATHER_SCHEMA_STATS('test', method_opt=>'for all columns size 1');

# 收集直方图的场景并使用默认策略
CALL DBMS_STATS.GATHER_SCHEMA_STATS('test');

```

当收集的用户下存在一些大表（行数在千万级别）时，可以在业务低峰期增大并行度来收集：

```sql
# 不收集直方图的场景
CALL DBMS_STATS.GATHER_SCHEMA_STATS('test', degree=>'16', method_opt=>'for all columns size 1');

# 收集直方图的场景并使用默认策略
CALL DBMS_STATS.GATHER_SCHEMA_STATS('test', degree=>'16');

```

如果用户下存在超大表（行数超过 1 亿）时，可以选择针对超大表开大并行单独收集，然后锁定超大表的统计信息再使用上述命令收集整个用户的，收集完成后在解锁超大表的统计信息，后续按照增量模式收集，示例如下：

```sql
CALL DBMS_STATS.GATHER_TABLE_STATS('test', 'big_table', degree=>128, method_opt=>'for all columns size 1');

CALL DBMS_STATS.LOCK_TABLE_STATS('test','big_table');

CALL DBMS_STATS.GATHER_SCHEMA_STATS('TEST', degree=>'16', method_opt=>'for all columns size 1');

CALL DBMS_STATS.UNLOCK_TABLE_STATS('test','big_table');

```

在每次收集后，务必执行健康检查：

```sql
-- 示例：验证 test.t1 是否收集成功
SELECT table_name, num_rows, last_analyzed
FROM oceanbase.DBA_TAB_STATISTICS
WHERE owner = 'test' AND table_name = 'T1' AND object_type = 'TABLE';

```

## 统计信息收集进度与健康状态监控

为什么需要监控？统计信息收集可能耗时数分钟至数小时。您需要：

- 实时了解任务是否仍在运行
 - 判断是否卡住或失败
 - 验证收集结果是否有效
 - 评估统计信息是否“过期”或“失真”

### 查询统计信息收集进度

OceanBase 数据库从 V4.2.0 版本开始支持统计信息收集监控诊断功能。手动或自动发起统计信息收集后，可以通过 `(G)V$OB_OPT_STAT_GATHER_MONITOR` 视图查询实时收集状态与进度。

有关该视图的字段含义、示例与更多诊断方法，参见 [统计信息收集监控诊断](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686955)。

#### 查看当前正在运行的收集任务

#### 说明

- MySQL 模式下通常使用 `oceanbase.GV$OB_OPT_STAT_GATHER_MONITOR`（或 `oceanbase.V$OB_OPT_STAT_GATHER_MONITOR`）。
 - Oracle 模式下通常使用 `SYS.GV$OB_OPT_STAT_GATHER_MONITOR`（或 `SYS.V$OB_OPT_STAT_GATHER_MONITOR`）。

```sql
SELECT
  tenant_id,
  svr_ip,
  svr_port,
  session_id,
  trace_id,
  task_id,
  type,
  task_start_time,
  task_duration_time,
  task_table_count,
  completed_table_count,
  running_table_owner,
  running_table_name,
  running_table_duration_time,
  running_table_progress
FROM oceanbase.GV$OB_OPT_STAT_GATHER_MONITOR
WHERE type = 'MANUAL GATHER';

```

| 字段 | 说明 |
| --- | --- |
| `TASK_TABLE_COUNT` | 该任务需要收集的表数量 |
| `COMPLETED_TABLE_COUNT` | 该任务已完成的表数量 |
| `RUNNING_TABLE_OWNER` / `RUNNING_TABLE_NAME` | 当前正在收集的表 |
| `RUNNING_TABLE_PROGRESS` | 当前正在收集表的进度（字符串形式展示） |

如果希望查看“当前租户在当前 OBServer 节点上”的实时状态，请使用 `V$OB_OPT_STAT_GATHER_MONITOR`。

#### 查看历史任务记录（任务级）

```sql
-- 查询手动收集任务的历史执行情况
SELECT
  tenant_id,
  task_id,
  type,
  status,
  table_count,
  failed_count,
  start_time,
  end_time
FROM oceanbase.DBA_OB_TASK_OPT_STAT_GATHER_HISTORY
WHERE type = 'MANUAL GATHER'
ORDER BY start_time DESC;

```

#### 查看历史任务记录（表级）

```sql
-- 查询手动收集过程中失败的表（若无失败则无返回）
SELECT
  owner,
  table_name,
  task_id,
  status,
  start_time,
  end_time,
  stat_refresh_failed_list,
  properties
FROM oceanbase.DBA_OB_TABLE_OPT_STAT_GATHER_HISTORY
WHERE status = 'FAILED'
ORDER BY start_time DESC;

```

> `STAT_REFRESH_FAILED_LIST` 表示“统计信息已收集完成，但刷新统计信息缓存失败”的节点列表。出现该字段时，建议结合视图信息排查相关节点状态，并在必要时刷新 Plan Cache。

### 验证统计信息是否生效或健康

收集完成后，需确认统计信息已写入并处于可用状态。

#### 检查表级统计信息是否存在

#### 说明

- MySQL 模式下可使用 `oceanbase.DBA_TAB_STATISTICS`、`oceanbase.DBA_TAB_COL_STATISTICS` 等视图。
 - Oracle 模式下可使用 `SYS.DBA_TAB_STATISTICS`、`SYS.DBA_TAB_COL_STATISTICS` 等视图。

```sql
SELECT
  table_name,
  num_rows,        -- 行数
  avg_row_len,     -- 平均行长度
  sample_size,     -- 采样大小
  last_analyzed,   -- 最后收集时间
  stale_stats,     -- 是否过期
  stattype_locked  -- 是否锁定
FROM oceanbase.DBA_TAB_STATISTICS
WHERE owner = 'test' AND table_name = 'T1' AND object_type = 'TABLE';

```

**健康标志**：

- `last_analyzed` 为近期时间（与本次收集时间一致）
 - `num_rows` / `sample_size` 等关键字段为非空且与业务规模大致匹配
 - `stale_stats = 'NO'`（统计信息未过期）

#### 检查列直方图是否生成（若指定了 SIZE > 1）

```sql
SELECT
  column_name,
  num_distinct,    -- 不同值数量
  num_nulls,       -- NULL 值数量
  num_buckets,     -- 桶个数
  histogram,       -- 直方图类型
  last_analyzed
FROM oceanbase.DBA_TAB_COL_STATISTICS
WHERE owner = 'test' AND table_name = 'T1';

```

**直方图健康判断**：

- `histogram` 字段显示直方图类型（例如 `HYBRID`），且 `num_buckets > 1` 时通常表示已生成直方图。
 - `num_distinct` / `num_nulls` 等统计值建议与业务预期做一致性校验（避免采样过小或策略不当导致失真）。

#### 检查统计信息是否被锁定（防止自动更新覆盖）

```sql
SELECT stattype_locked
FROM oceanbase.DBA_TAB_STATISTICS
WHERE owner = 'test' AND table_name = 'BIG_TABLE' AND object_type = 'TABLE';

```

- `stattype_locked = 'ALL'`：已锁定
 - `NULL`：未锁定

### 常见问题诊断

| 问题现象 | 可能原因 | 解决方案 |
| --- | --- | --- |
| 收集任务长时间无进展 | 表极大、并行度低、资源争抢 | 增加 `degree`，在业务低峰期执行 |
| `num_rows = 0` 或 `NULL` | 收集未完成或失败 | 检查 `DBA_OB_TASK_OPT_STAT_GATHER_HISTORY`、`DBA_OB_TABLE_OPT_STAT_GATHER_HISTORY` |
| 直方图未生成 | `method_opt` 未指定 `SIZE > 1` | 显式设置 `FOR COLUMNS col SIZE 254` |
| 查询仍走错误计划 | 统计信息未刷新 Plan Cache | 执行 `ALTER SYSTEM FLUSH PLAN CACHE;` |

 上一篇 下一篇 ![有帮助](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) 咨询热线
