基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
系统字典视图 DBA_OB_TABLE_STAT_STALE_INFO 的介绍说明
更新时间:2026-05-25 09:11
统计信息的准确与否对于执行计划的生成至关重要,通常情况下统计信息越准确,就更容易生成更好的计划。从 OceanBase 数据库 V4.2.0 版本开始提供一个展示表上统计信息是否已经陈旧的视图 DBA_OB_TABLE_STAT_STALE_INFO,让用户能够方便地查看自上次收集统计信息以来每个表、分区上发生的 DML(INSERT、UPDATE、DELETE)操作的影响行数以及表级、分区级的统计信息是否已经过期。
详细说明
字段说明
| 字段 | 类型 | 是否为 NULL | 描述 |
|---|---|---|---|
| DATABASE_NAME | varchar(128) | NO | 表所在的数据库名。 |
| TABLE_NAME | varchar(128) | NO | 表名。 |
| PARTITION_NAME | varchar(128) | YES | 分区名。当分区表此列的值为 NULL 时,表示当前记录在表级别进行了汇总。 |
| SUBPARTITION_NAME | varchar(128) | YES | 二级分区名。当二级分区表此列的值为 NULL 时,表示当前记录在表级别或分区级别进行了汇总。 |
| LAST_ANALYZED_ROWS | bigint(20) | YES | 上次收集统计信息时的行数。值为 NULL 表示没有收集过统计信息。 |
| LAST_ANALYZED_TIME | timestamp(6) | YES | 上次收集统计信息时的时间。值为 NULL 表示没有收集过统计信息。 |
| INSERTS | bigint(21) | NO | 从上次收集统计信息起发生了多少行的插入。 |
| UPDATES | bigint(21) | NO | 从上次收集统计信息起发生了多少行的更新。 |
| DELETES | bigint(21) | NO | 从上次收集统计信息起发生了多少行的删除。 |
| STALE_PERCENT | bigint(21) | NO | 判定统计信息过期的百分比。 |
| IS_STALE | varchar(3) | NO | 统计信息是否过期。YES:表示过期。当表收集过统计信息时,过期的条件为 INSERTS + UPDATES + DELETES > LAST_ANALYZED_ROWS * STALE_PERCENT / 100;当表没有收集过统计信息时,过期的条件为 INSERTS + UPDATES + DELETES > 0。 NO :表示未过期。 |
其中,IS_STALE 为动态生成列,其值取决于 LAST_ANALYZED_TIME、LAST_ANALYZED_ROWS、INSERTS、UPDATES、DELETES、STALE_PERCENT 等列当前的取值:
如果
INSERTS + UPDATES + DELETES超过LAST_ANALYZED_ROWS * STALE_PERCENT / 100,则IS_STALE=YES。如果
LAST_ANALYZED_TIME=NULL且INSERTS + UPDATES + DELETES > 0,则 IS_STALE=YES。否则
IS_STALE=NO。
IS_STALE 列用于指示下次每日定时统计信息收集时,是否需要对该表、分区收集统计信息
如果
IS_STALE=YES,则下次每日定时统计信息收集窗口需要重新收集统计信息。如果
IS_STALE=NO,则下次每日定时统计信息收集窗口不会重新收集统计信息。
目前默认的每日自动统计信息收集窗口如下表所示:其中周一到周五的任务默认开始时间为 22:00,最大收集时长 4 小时,周六周日的默认开始时间为 6:00,最大收集时长为 20 小时。
| 维护窗口名称 | 开始时间/频率 | 最大收集时长 |
|---|---|---|
| MONDAY_WINDOW | 22:00/per week | 4 hours |
| TUESDAY_WINDOW | 22:00/per week | 4 hours |
| WEDNESDAY_WINDOW | 22:00/per week | 4 hours |
| THURSDAY_WINDOW | 22:00/per week | 4 hours |
| FRIDAY_WINDOW | 22:00/per week | 4 hours |
| SATURDAY_WINDOW | 6:00/per week | 20 hours |
| SUNDAY_WINDOW | 6:00/per week | 20 hours |
比如下面的 t4 表自 2025-01-21 号以后因为数据未变更,2025-01-21 的每日定时统计信息收集后,再未触发过每日定时统计信息的收集:
MySQL [test]> select table_schema, table_name, create_time, update_time from information_schema.tables where table_schema='test' and table_name='t4'\G
*************************** 1. row ***************************
table_schema: test
table_name: t4
create_time: 2025-01-21 21:51:31
update_time: 2025-01-21 21:51:31
1 row in set (0.005 sec)
MySQL [test]> select * from t4;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.000 sec)
MySQL [test]> select now() ; select * from oceanbase.dba_ob_table_stat_stale_info where database_name='test' and table_name='t4'\G
+---------------------+
| now() |
+---------------------+
| 2025-03-02 21:55:39 |
+---------------------+
1 row in set (0.000 sec)
*************************** 1. row ***************************
DATABASE_NAME: test
TABLE_NAME: t4
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
LAST_ANALYZED_ROWS: 1
LAST_ANALYZED_TIME: 2025-01-21 22:00:01.516323
INSERTS: 0
UPDATES: 0
DELETES: 0
STALE_PERCENT: 10
IS_STALE: NO
1 row in set (0.008 sec)
手工对表收集统计信息后会自动更新 DBA_OB_TABLE_STAT_STALE_INFO 视图相关记录
通过 analyze table 或 dbms_stats.gather_table_stats 手工对表收集统计信息后,(即使原来 IS_STALE=YES)系统会自动更新该视图的 LAST_ANALYZED_TIME、LAST_ANALYZED_ROWS、INSERTS、UPDATES、DELETES、IS_STALE 等各列信息:
MySQL [test]> select now() ; select * from oceanbase.dba_ob_table_stat_stale_info where database_name='test' and table_name='t1'\G
+---------------------+
| now() |
+---------------------+
| 2025-03-02 22:00:17 |
+---------------------+
1 row in set (0.000 sec)
*************************** 1. row ***************************
DATABASE_NAME: test
TABLE_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
LAST_ANALYZED_ROWS: 1000000
LAST_ANALYZED_TIME: 2025-03-02 21:14:37.156974
INSERTS: 150508
UPDATES: 0
DELETES: 19
STALE_PERCENT: 10
IS_STALE: YES
1 row in set (0.007 sec)
MySQL [test]> select now(); analyze table t1;
+---------------------+
| now() |
+---------------------+
| 2025-03-02 22:00:30 |
+---------------------+
1 row in set (0.000 sec)
Query OK, 0 rows affected (4.477 sec)
MySQL [test]> select now() ; select * from oceanbase.dba_ob_table_stat_stale_info where database_name='test' and table_name='t1'\G
+---------------------+
| now() |
+---------------------+
| 2025-03-02 22:00:46 |
+---------------------+
1 row in set (0.000 sec)
*************************** 1. row ***************************
DATABASE_NAME: test
TABLE_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
LAST_ANALYZED_ROWS: 999981
LAST_ANALYZED_TIME: 2025-03-02 22:00:34.655353
INSERTS: 0
UPDATES: 0
DELETES: 0
STALE_PERCENT: 10
IS_STALE: NO
1 row in set (0.007 sec)
手工对全库收集统计信息后会自动更新 DBA_OB_TABLE_STAT_STALE_INFO 视图相关记录
通过 dbms_stats.gather_schema_stats 手工对表收集统计信息后,(即使原来 IS_STALE=YES)系统会自动更新该视图的 LAST_ANALYZED_TIME、LAST_ANALYZED_ROWS、INSERTS、UPDATES、DELETES、IS_STALE 等各列信息:
MySQL [test]> select now() ; select * from oceanbase.dba_ob_table_stat_stale_info where database_name='test' and table_name='t1'\G
+---------------------+
| now() |
+---------------------+
| 2025-03-02 22:08:01 |
+---------------------+
1 row in set (0.000 sec)
*************************** 1. row ***************************
DATABASE_NAME: test
TABLE_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
LAST_ANALYZED_ROWS: 999981
LAST_ANALYZED_TIME: 2025-03-02 22:00:34.655353
INSERTS: 0
UPDATES: 0
DELETES: 20
STALE_PERCENT: 10
IS_STALE: NO
1 row in set (0.007 sec)
MySQL [test]> select now() ; call dbms_stats.gather_schema_stats('test', degree=>128);
+---------------------+
| now() |
+---------------------+
| 2025-03-02 22:09:04 |
+---------------------+
1 row in set (0.000 sec)
Query OK, 0 rows affected (6.827 sec)
MySQL [test]> select now() ; select * from oceanbase.dba_ob_table_stat_stale_info where database_name='test' and table_name='t1'\G
+---------------------+
| now() |
+---------------------+
| 2025-03-02 22:11:12 |
+---------------------+
1 row in set (0.000 sec)
*************************** 1. row ***************************
DATABASE_NAME: test
TABLE_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
LAST_ANALYZED_ROWS: 999961
LAST_ANALYZED_TIME: 2025-03-02 22:09:10.884371
INSERTS: 0
UPDATES: 0
DELETES: 0
STALE_PERCENT: 10
IS_STALE: NO
1 row in set (0.008 sec)
自动在线统计信息收集会自动更新 DBA_OB_TABLE_STAT_STALE 视图相关记录
从 OceanBase 数据库 V4.1 版本开始支持在线统计信息收集,在批量导入数据的过程中,可以实时收集统计信息,不需要额外的发起收集任务,减少了运维操作,提高统计信息收集性能。一旦发生了在线统计信息收集,(即使原来 IS_STALE=YES)系统会自动更新该视图的 LAST_ANALYZED_TIME、LAST_ANALYZED_ROWS、INSERTS、UPDATES、DELETES、IS_STALE 等各列信息:
MySQL [test]> select now() ; insert /*+ enable_parallel_dml parallel(3) */ into t1 select * from t2;
+---------------------+
| now() |
+---------------------+
| 2025-03-02 22:18:37 |
+---------------------+
1 row in set (0.000 sec)
Query OK, 1000000 rows affected (5.441 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
MySQL [test]> select * from oceanbase.dba_ob_table_stat_stale_info where database_name='test' order by last_analyzed_time desc limit 1\G
*************************** 1. row ***************************
DATABASE_NAME: test
TABLE_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
LAST_ANALYZED_ROWS: 1999961
LAST_ANALYZED_TIME: 2025-03-02 22:18:43.320842
INSERTS: 972733
UPDATES: 0
DELETES: 0
STALE_PERCENT: 10
IS_STALE: YES
1 row in set (0.011 sec)
目前在线统计信息收集的主要触发场景如下:
CREATE TABLE...AS SELECT(即 CTAS)。在系统变量
_optimizer_gather_stats_on_load为 True 时,CTAS 默认启动在线收集统计信息功能。如果需要禁用该功能,可以使用NO_GATHER_OPTIMIZER_STATISTICSHint,示例如下:CREATE TABLE table_name AS SELECT /*+NO_GATHER_OPTIMIZER_STATISTICS*/* FROM...INSERT INTO ... SELECT ...。在系统变量
_optimizer_gather_stats_on_load为 True 时,使用GATHER_OPTIMIZER_STATISTICSHint 或者APPENDHint 启动在线收集统计信息功能。 示例如下:INSERT /*+GATHER_OPTIMIZER_STATISTICS*/ INTO table_name SELECT * FROM table_name注意
OceanBase 数据库暂不支持通过
INSERT /*+GATHER_OPTIMIZER_STATISTICS*/ INTO table_name VALUES()...和INSERT /*+GATHER_OPTIMIZER_STATISTICS*/ INTO table_name(column_name) VALUES() | SELECT...语句在线收集统计信息。PDML。
通过
ENABLE_PARALLEL_DMLHint 或者通过ALTER SESSION ENABLE PARALLEL DML;设置系统并行模式的方式让插入操作以并行的方式进行。
可以通过调整表的 stale_percent 来修改视图中的 IS_STALE
默认的 STALE_PERCENT 值为 10,即如果增量修改的行数超过上次统计的行数的 10%,则该表的统计信息会认为过旧。可以通过调整 STALE_PERCENT 的值来影响 IS_STALE 生成列的值:
MySQL [test]> select * from oceanbase.dba_ob_table_stat_stale_info where database_name='test' order by last_analyzed_time desc limit 1\G
*************************** 1. row ***************************
DATABASE_NAME: test
TABLE_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
LAST_ANALYZED_ROWS: 1999961
LAST_ANALYZED_TIME: 2025-03-02 22:18:43.320842
INSERTS: 972733
UPDATES: 0
DELETES: 0
STALE_PERCENT: 10
IS_STALE: YES
1 row in set (0.011 sec)
MySQL [test]> CALL DBMS_STATS.SET_TABLE_PREFS('test', 't1', 'STALE_PERCENT', 100);
Query OK, 0 rows affected (0.018 sec)
MySQL [test]> SELECT DBMS_STATS.GET_PREFS ('STALE_PERCENT', 'test', 't1');
+------------------------------------------------------+
| DBMS_STATS.GET_PREFS ('STALE_PERCENT', 'test', 't1') |
+------------------------------------------------------+
| 100 |
+------------------------------------------------------+
1 row in set (0.383 sec)
MySQL [test]> select * from oceanbase.dba_ob_table_stat_stale_info where database_name='test' order by last_analyzed_time desc limit 1\G
*************************** 1. row ***************************
DATABASE_NAME: test
TABLE_NAME: t1
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
LAST_ANALYZED_ROWS: 1999961
LAST_ANALYZED_TIME: 2025-03-02 22:18:43.320842
INSERTS: 972733
UPDATES: 0
DELETES: 0
STALE_PERCENT: 100
IS_STALE: NO
1 row in set (0.011 sec)
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
适用版本
OceanBase 数据库 V4.2.0 及更高版本。