DBE_STATS
高级包DBE_STATS提供了统计信息管理的功能,包括锁定、解锁、导出、导入、设置、回退历史统计信息等。DBE_STATS支持的接口请参见表1。
- DBE_STATS不支持临时表。
- DBE_STATS统计信息管理规则同现有的统计信息管理规则一致,仅支持内核已有统计信息相关功能。
- DBE_STATS和多版本统计信息管理不支持M兼容模式。
- DBE_STATS不支持删除统计信息接口。
- 多版本统计信息管理功能要求相关GUC参数所有节点一致:
- 要求历史统计信息保留时间stats_history_retention_time、历史统计信息保留条数上限stats_history_record_limit所有节点设置一致。如果不同节点GUC参数值不一致,会导致不同节点同一对象的历史统计信息不一致,回退时可能在某个节点查找不到指定时间戳的历史统计信息,进而导致回退失败。
- 扩容节点后使用回退接口,指定扩容前的时间戳回退时,新增加节点复用了CN的元数据,历史统计信息也属于元数据之一,后续按照该节点的历史统计信息进行统计信息回退。
- 统计信息的修改(导入、回退、设置)会导致计划缓存失效,每个缓存的执行计划会记录其依赖的统计信息版本,如果当前统计信息版本与缓存计划记录的版本不一致,则判定缓存计划失效,需重新生成。
接口介绍
| 接口名称 | 描述 | 权限要求 |
|---|---|---|
| 锁定表级统计信息。 | 使用该接口时,用户需要对指定的表拥有与ANALYZE命令相同的权限。有关权限的详细信息,请参见ANALYZE | ANALYSE。 | |
| 锁定分区级统计信息。 | ||
| 锁定列级统计信息。 | ||
| 锁定指定Schema下所有表相关的统计信息。 |
| |
| 解锁表级统计信息。 | 使用该接口时,用户需要对指定的表拥有与ANALYZE命令相同的权限。有关权限的详细信息,请参见ANALYZE | ANALYSE。 | |
| 解锁分区级统计信息。 | ||
| 解锁列级统计信息。 | ||
| 解锁指定Schema下所有表相关的统计信息。 |
| |
| 回退表级统计信息到指定时间点。 | 使用该接口时,用户需要对指定的表拥有与ANALYZE命令相同的权限。有关权限的详细信息,请参见ANALYZE | ANALYSE。 | |
| 回退分区级统计信息到指定时间点。 | ||
| 回退列级统计信息到指定时间点。 | ||
| 回退指定Schema下所有表相关的统计信息到指定时间点。 |
| |
| 清除指定时间节点前的所有历史统计信息。 | 只有初始用户可调用该接口。 | |
| 获取历史统计信息的保留时间。 | - | |
| 获取最早可用的历史统计信息的时间。 | - | |
| 创建用于保存统计信息的统计表。 | 要调用此过程创建统计表,需要用户拥有在指定Schema与指定tablespace下创建表和创建索引的权限。 | |
| 删除用于保存统计信息的统计表。 | 要调用此过程删除统计表,需要用户拥有在指定Schema下删除表和删除索引的权限。 | |
| 检索指定索引的统计信息并存储在用户统计信息表中。 |
| |
| 检索指定表的统计信息并存储在用户统计信息表中。 | ||
| 检索指定列的统计信息并存储在用户统计信息表中。 | ||
| 检索指定schema的统计信息并存储在用户统计信息表中。 | ||
| 检索当前database的统计信息并存储在用户统计信息表中。 |
| |
| 从用户统计信息表中检索指定索引的统计信息,并将其写回系统表。 |
| |
| 从用户统计信息表中检索指定表的统计信息,并将其写回系统表。 | ||
| 从用户统计信息表中检索指定列的统计信息,并将其写回系统表。 | ||
| 从用户统计信息表中检索指定schema的统计信息,并将其写回系统表。 | ||
| 从用户统计信息表中检索指定database的统计信息,并将其写回系统表。 |
| |
| 设置列相关的统计信息,包括单列、多列、表达式统计信息。 | 使用该接口时,用户需要对指定的表拥有与ANALYZE命令相同的权限。有关权限的详细信息,请参见ANALYZE | ANALYSE。 | |
| 设置索引相关的统计信息。 | ||
| 设置表相关的统计信息。 | ||
| 获取Unique SQL ID对应语句所有涉及的表,如果包含多张表,则返回多行记录。 | 使用该接口时,用户的权限需要满足以下其中一种情况:
| |
| 获取Unique SQL ID对应语句所有涉及的表,以及收集对应表的统计信息。对于收集成功的表,如果包含多张表,则返回多行记录。 | 使用该接口时,用户的权限需要满足以下其中一种情况:
| |
| 用于库级统计信息导出和导入,以及计划调优语句元信息导出。 |
|
- DBE_STATS.LOCK_TABLE_STATS
锁定一个表的统计信息。锁定后,该表的统计信息无法更新,该表下级索引也会同步被锁定。该接口无返回值。
DBE_STATS.LOCK_TABLE_STATS原型为:
DBE_STATS.LOCK_TABLE_STATS( ownname VARCHAR2, tabname VARCHAR2 );
表2 DBE_STATS.LOCK_TABLE_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
varchar2
是
要锁定的表所属的Schema名称,该参数为空时,默认为当前Schema。
tabname
varchar2
否
要锁定的表的名称。
- 可以通过查看表的reloptions中的stat_state状态获取该表的锁定状态。
- 当一个表处于锁定状态时,其统计信息无法更新。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
-- 建表。 gaussdb=# CREATE SCHEMA dbe_stats_lock; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA=dbe_stats_lock; SET gaussdb=# CREATE TABLE t1(a int,b int) distribute by hash(a); CREATE TABLE -- 锁定表,查看其锁定状态。 gaussdb=# CALL DBE_STATS.LOCK_TABLE_STATS(ownname=>'dbe_stats_lock',tabname=>'t1'); lock_table_stats ------------------ (1 row) gaussdb=# SELECT relname,instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock FROM PG_CLASS WHERE relname='t1' AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_lock'); relname | exist_lock ---------+------------ t1 | t (1 row) -- 锁定后analyze, 发生报错。 gaussdb=# ANALYZE t1; ERROR: The statistics is locked, cannot be updated. -- 删除表、删除命名空间。 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_lock; DROP SCHEMA
- DBE_STATS.LOCK_PARTITION_STATS
锁定一个分区的统计信息。锁定后,该分区的统计信息无法更新,该分区下级索引也会同步锁定。该接口无返回值。
DBE_STATS.LOCK_PARTITION_STATS原型为:
DBE_STATS.LOCK_PARTITION_STATS( ownname VARCHAR2, tabname VARCHAR2, partname VARCHAR2 );表3 DBE_STATS.LOCK_PARTITION_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
varchar2
是
要锁定的分区所属的Schema名称,该参数为空时,默认为当前Schema。
tabname
varchar2
否
要锁定的分区所属的表的名称。
partname
varchar2
否
要锁定的分区的名称。
- 可以通过查看该分区的reloptions中的stat_state状态获取该表的锁定状态。
- 当该分区或该表所属的表处于锁定状态时,其统计信息无法更新。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
-- 建表。 gaussdb=# CREATE SCHEMA dbe_stats_lock; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA=dbe_stats_lock; SET gaussdb=# CREATE TABLE upart_table(a int, b int, c int) distribute by hash(a) PARTITION BY RANGE(a) ( PARTITION p1 VALUES LESS THAN(1200), PARTITION p2 VALUES LESS THAN(2400), PARTITION p3 VALUES LESS THAN(MAXVALUE) ); CREATE TABLE -- 锁定一个分区,其他分区及表不受影响。 gaussdb=# CALL DBE_STATS.LOCK_PARTITION_STATS(ownname=>'dbe_stats_lock',tabname=>'upart_table',partname=>'p1'); lock_partition_stats ---------------------- (1 row) gaussdb=# SELECT relname,instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock FROM PG_CLASS WHERE relname='upart_table'; relname | exist_lock -------------+------------ upart_table | f (1 row) gaussdb=# SELECT relname,instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock FROM PG_PARTITION WHERE parentid='upart_table'::REGCLASS ORDER BY oid; relname | exist_lock -------------+------------ upart_table | f p1 | t p2 | f p3 | f (4 rows) -- 删除表、命名空间。 gaussdb=# DROP TABLE upart_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_lock; DROP SCHEMA
- DBE_STATS.LOCK_COLUMN_STATS
锁定一个列的统计信息。锁定后,该列的统计信息无法更新。该接口无返回值。
DBE_STATS.LOCK_COLUMN_STATS原型为:
DBE_STATS.LOCK_COLUMN_STATS( ownname VARCHAR2, tabname VARCHAR2, colname VARCHAR2, partname VARCHAR2 DEFAULT NULL );表4 DBE_STATS.LOCK_COLUMN_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
varchar2
是
要锁定的列所属的Schema的名称,该参数为空时,默认为当前Schema。
tabname
varchar2
否
要锁定的列所属的表的名称。
colname
varchar2
否
要锁定的列的名称。
partname
varchar2
是
要锁定的列所属的分区的名称,默认为空。
- 当partname为空时,默认锁定该列表级统计信息。
- 若不存在该表的列级统计信息,则锁定可执行成功,但实际未生效。
- 可查看PG_STATISTIC、PG_STATISTIC_EXT中的stastate获取锁定状态。
- 锁定多列时,需先查询PG_STATISTIC_EXT中的staextname字段,获取多列别名作为colname参数传入。
- 当某一列被锁定或其所属的表或分区被锁定时,其统计信息无法更新,该列被锁定的信息不会回显,需要在日志中通过DEBUG2级别的DBE_STATS的logging_module查看。
- 当ownname参数值设置为null时使用当前schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
-- 建表,收集统计信息。 gaussdb=# CREATE SCHEMA dbe_stats_lock; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA=dbe_stats_lock; SET gaussdb=# CREATE TABLE t1(a int,b int) distribute by hash(a); CREATE TABLE gaussdb=# INSERT INTO t1 VALUES(generate_series(1,100),1); INSERT 0 100 gaussdb=# ANALYZE t1; ANALYZE -- 锁定列后,查看列的锁定状态。 gaussdb=# CALL DBE_STATS.LOCK_COLUMN_STATS(ownname=>'dbe_stats_lock',tabname=>'t1',colname=>'a'); lock_column_stats ------------------- (1 row) gaussdb=# SELECT staattnum,stastate FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS ORDER BY 1,2; staattnum | stastate -----------+---------- 1 | l 2 | u (2 rows) -- 删除表、命名空间。 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_lock; DROP SCHEMA
- DBE_STATS.LOCK_SCHEMA_STATS
锁定一个指定Schema下所有表、表下级索引的统计信息。该接口无返回值。
DBE_STATS.LOCK_SCHEMA_STATS原型为:
DBE_STATS.LOCK_SCHEMA_STATS( ownname VARCHAR2 );表5 DBE_STATS.LOCK_SCHEMA_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
varchar2
是
指定的Schema名称,该参数为空时,默认为当前Schema。
当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_lock_schema CASCADE; NOTICE: schema "dbe_stats_lock_schema" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表 gaussdb=# CREATE SCHEMA dbe_stats_lock_schema; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_lock_schema; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by hash(a); CREATE TABLE gaussdb=# CREATE TABLE t2(a int, b int) distribute by hash(a); CREATE TABLE gaussdb=# -- 锁定schema gaussdb=# CALL DBE_STATS.LOCK_SCHEMA_STATS(ownname=>'dbe_stats_lock_schema'); lock_schema_stats ------------------- (1 row) gaussdb=# -- 验证: t1和t2都应被锁定 (exist_lock = t) gaussdb=# SELECT relname, instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock gaussdb-# FROM PG_CLASS gaussdb-# WHERE relname IN ('t1','t2') gaussdb-# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_lock_schema') gaussdb-# ORDER BY 1; relname | exist_lock ---------+------------ t1 | t t2 | t (2 rows) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE t2; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_lock_schema; DROP SCHEMA - DBE_STATS.UNLOCK_TABLE_STATS
解锁一个表的统计信息。解锁后,该表的统计信息可以更新。该表下级索引会同步解锁。该接口无返回值。
DBE_STATS.UNLOCK_TABLE_STATS原型为:
DBE_STATS.UNLOCK_TABLE_STATS( ownname VARCHAR2, tabname VARCHAR2 );
表6 DBE_STATS.UNLOCK_TABLE_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
varchar2
是
要解锁的表所属的Schema的名称,该参数为空时,默认为当前Schema。
tabname
varchar2
否
要解锁的表的名称。
- 可以通过查看该表的reloptions中的stat_state状态获取该表的锁定状态。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_lock_unlock_table CASCADE; NOTICE: schema "dbe_stats_lock_unlock_table" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表 gaussdb=# CREATE SCHEMA dbe_stats_lock_unlock_table; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_lock_unlock_table; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by hash(a); CREATE TABLE gaussdb=# -- 先锁定表 gaussdb=# CALL DBE_STATS.LOCK_TABLE_STATS(ownname=>'dbe_stats_lock_unlock_table', tabname=>'t1'); lock_table_stats ------------------ (1 row) gaussdb=# -- 验证已锁定 gaussdb=# SELECT relname, instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock gaussdb-# FROM PG_CLASS gaussdb-# WHERE relname='t1' gaussdb-# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_lock_unlock_table'); relname | exist_lock ---------+------------ t1 | t (1 row) gaussdb=# -- 解锁表 gaussdb=# CALL DBE_STATS.UNLOCK_TABLE_STATS(ownname=>'dbe_stats_lock_unlock_table', tabname=>'t1'); unlock_table_stats -------------------- (1 row) gaussdb=# -- 验证已解锁 (exist_lock = f) gaussdb=# SELECT relname, instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock gaussdb-# FROM PG_CLASS gaussdb-# WHERE relname='t1' gaussdb-# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_lock_unlock_table'); relname | exist_lock ---------+------------ t1 | f (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_lock_unlock_table; DROP SCHEMA
- DBE_STATS.UNLOCK_PARTITION_STATS
解锁一个分区的统计信息。解锁后,该分区的统计信息可以更新。该分区下级索引会同步解锁。该接口无返回值。
DBE_STATS.UNLOCK_PARTITION_STATS原型为:
DBE_STATS.UNLOCK_PARTITION_STATS( ownname VARCHAR2, tabname VARCHAR2, partname VARCHAR2 );表7 DBE_STATS.UNLOCK_PARTITION_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
varchar2
是
要解锁的分区所属的Schema的名称,该参数为空时,默认为当前Schema。
tabname
varchar2
否
要解锁的分区所属的表的名称。
partname
varchar2
否
要解锁的分区的名称。
- 可查看该分区的reloptions中stat_state状态获取该表的锁定状态。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_lock_unlock_partition CASCADE; NOTICE: schema "dbe_stats_lock_unlock_partition" does not exist, skipping DROP SCHEMA gaussdb=# -- 建分区表 gaussdb=# CREATE SCHEMA dbe_stats_lock_unlock_partition; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_lock_unlock_partition; SET gaussdb=# CREATE TABLE upart_table(a int, b int, c int) distribute by hash(a) PARTITION BY RANGE(a) gaussdb-# ( gaussdb(# PARTITION p1 VALUES LESS THAN(1200), gaussdb(# PARTITION p2 VALUES LESS THAN(2400), gaussdb(# PARTITION p3 VALUES LESS THAN(MAXVALUE) gaussdb(# ); CREATE TABLE gaussdb=# -- 先锁定p1 gaussdb=# CALL DBE_STATS.LOCK_PARTITION_STATS(ownname=>'dbe_stats_lock_unlock_partition', tabname=>'upart_table', partname=>'p1'); lock_partition_stats ---------------------- (1 row) gaussdb=# -- 验证p1已锁定 gaussdb=# SELECT relname, instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock gaussdb-# FROM PG_PARTITION gaussdb-# WHERE parentid='upart_table'::REGCLASS gaussdb-# ORDER BY 1; relname | exist_lock -------------+------------ p1 | t p2 | f p3 | f upart_table | f (4 rows) gaussdb=# -- 解锁p1 gaussdb=# CALL DBE_STATS.UNLOCK_PARTITION_STATS(ownname=>'dbe_stats_lock_unlock_partition', tabname=>'upart_table', partname=>'p1'); unlock_partition_stats ------------------------ (1 row) gaussdb=# -- 验证p1已解锁 (全部 exist_lock = f) gaussdb=# SELECT relname, instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock gaussdb-# FROM PG_PARTITION gaussdb-# WHERE parentid='upart_table'::REGCLASS gaussdb-# ORDER BY 1; relname | exist_lock -------------+------------ p1 | f p2 | f p3 | f upart_table | f (4 rows) gaussdb=# -- 清理 gaussdb=# DROP TABLE upart_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_lock_unlock_partition; DROP SCHEMA
- DBE_STATS.UNLOCK_COLUMN_STATS
解锁一个列的统计信息。解锁后,该列的统计信息可以更新。该接口无返回值。
DBE_STATS.UNLOCK_COLUMN_STATS原型为:
DBE_STATS.UNLOCK_COLUMN_STATS( ownname VARCHAR2, tabname VARCHAR2, colname VARCHAR2, partname VARCHAR2 DEFAULT NULL );表8 DBE_STATS.UNLOCK_COLUMN_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
varchar2
是
要解锁的列所属的Schema的名称,该参数为空时,默认为当前Schema。
tabname
varchar2
否
要解锁的列所属的表的名称。
colname
varchar2
否
要解锁的列的名称。
partname
varchar2
是
要解锁的列所属的分区的名称,默认为空。
- 当partname为空时,默认解锁该列表级统计信息,以及解锁其级联分区列级统计信息。
- 可查看PG_STATISTIC、PG_STATISTIC_EXT中的stastate状态获取锁定状态。
- 解锁多列时,需先查询PG_STATISTIC_EXT中的staextname字段,获取多列别名作为colname参数传入。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_lock_unlock_column CASCADE; NOTICE: schema "dbe_stats_lock_unlock_column" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集统计信息 gaussdb=# CREATE SCHEMA dbe_stats_lock_unlock_column; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_lock_unlock_column; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by hash(a); CREATE TABLE gaussdb=# INSERT INTO t1 VALUES(generate_series(1,100), 1); INSERT 0 100 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 先锁定列a gaussdb=# CALL DBE_STATS.LOCK_COLUMN_STATS(ownname=>'dbe_stats_lock_unlock_column', tabname=>'t1', colname=>'a'); lock_column_stats ------------------- (1 row) gaussdb=# -- 验证列a已锁定 (stastate='l') gaussdb=# SELECT staattnum, stastate gaussdb-# FROM PG_STATISTIC gaussdb-# WHERE starelid='t1'::REGCLASS gaussdb-# ORDER BY 1, 2; staattnum | stastate -----------+---------- 1 | l 2 | u (2 rows) gaussdb=# -- 解锁列a gaussdb=# CALL DBE_STATS.UNLOCK_COLUMN_STATS(ownname=>'dbe_stats_lock_unlock_column', tabname=>'t1', colname=>'a'); unlock_column_stats --------------------- (1 row) gaussdb=# -- 验证列a已解锁 (stastate='u') gaussdb=# SELECT staattnum, stastate gaussdb-# FROM PG_STATISTIC gaussdb-# WHERE starelid='t1'::REGCLASS gaussdb-# ORDER BY 1, 2; staattnum | stastate -----------+---------- 1 | u 2 | u (2 rows) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_lock_unlock_column; DROP SCHEMA - DBE_STATS.UNLOCK_SCHEMA_STATS
解锁一个指定Schema下所有表、表下级索引的统计信息。该接口无返回值。
DBE_STATS.UNLOCK_SCHEMA_STATS原型为:
DBE_STATS.UNLOCK_SCHEMA_STATS( ownname VARCHAR2 );表9 DBE_STATS.UNLOCK_SCHEMA_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
varchar2
是
指定的Schema名称,该参数为空时,默认为当前Schema。
当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_lock_unlock_schema CASCADE; NOTICE: schema "dbe_stats_lock_unlock_schema" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表 gaussdb=# CREATE SCHEMA dbe_stats_lock_unlock_schema; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_lock_unlock_schema; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by hash(a); CREATE TABLE gaussdb=# CREATE TABLE t2(a int, b int) distribute by hash(a); CREATE TABLE gaussdb=# -- 先锁定schema gaussdb=# CALL DBE_STATS.LOCK_SCHEMA_STATS(ownname=>'dbe_stats_lock_unlock_schema'); lock_schema_stats ------------------- (1 row) gaussdb=# -- 验证已锁定 (exist_lock = t) gaussdb=# SELECT relname, instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock gaussdb-# FROM PG_CLASS gaussdb-# WHERE relname IN ('t1','t2') gaussdb-# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_lock_unlock_schema') gaussdb-# ORDER BY 1; relname | exist_lock ---------+------------ t1 | t t2 | t (2 rows) gaussdb=# -- 解锁schema gaussdb=# CALL DBE_STATS.UNLOCK_SCHEMA_STATS(ownname=>'dbe_stats_lock_unlock_schema'); unlock_schema_stats --------------------- (1 row) gaussdb=# -- 验证已解锁 (exist_lock = f) gaussdb=# SELECT relname, instr(reloptions::text,'stat_state=locked',1,1) <> 0 AS exist_lock gaussdb-# FROM PG_CLASS gaussdb-# WHERE relname IN ('t1','t2') gaussdb-# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_lock_unlock_schema') gaussdb-# ORDER BY 1; relname | exist_lock ---------+------------ t1 | f t2 | f (2 rows) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE t2; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_lock_unlock_schema; DROP SCHEMA - DBE_STATS.RESTORE_TABLE_STATS
将表的统计信息回退到指定的时间节点,选择该时间节点前最后一次收集的统计信息载入系统表,同时级联其下级未被锁定的分区、索引、列级统计信息。该接口无返回值。
DBE_STATS.RESTORE_TABLE_STATS原型为:
DBE_STATS.RESTORE_TABLE_STATS( ownname VARCHAR2, tabname VARCHAR2, as_of_timestamp TIMESTAMPTZ, restore_cluster_index BOOLEAN DEFAULT NULL, force BOOLEAN DEFAULT FALSE, no_invalidate BOOLEAN DEFAULT NULL );表10 DBE_STATS.RESTORE_TABLE_STATS接口参数介绍 参数
类型
是否允许为空
描述
ownname
VARCHAR2
是
要回退的表所属的Schema名称,该参数为空时,默认为当前Schema。
tabname
VARCHAR2
否
要回退的表的名称。
as_of_timestamp
timestamp with time zone
否
要回退的目标时间节点。
restore_cluster_index
BOOLEAN
是
暂不支持。
force
BOOLEAN
是
是否在统计信息被锁定时强行回退的标志位,默认为false。
no_invalidate
BOOLEAN
是
暂不支持。
- 调用该接口时,同时回退其下级分区、索引、列的统计信息,如果其下级的分区或列被锁定,则直接跳过。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_restore_table CASCADE; NOTICE: schema "dbe_stats_restore_table" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集两次统计信息 gaussdb=# CREATE SCHEMA dbe_stats_restore_table; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_restore_table; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 查看历史表 (应有两条记录: reltuples=3 和 reltuples=6) gaussdb=# SELECT relname, reltuples FROM GS_TABLESTATS_HISTORY WHERE relid='t1'::regclass ORDER BY 1, 2; relname | reltuples ---------+----------- t1 | 3 t1 | 6 (2 rows) gaussdb=# -- 查看当前系统表 (reltuples=6) gaussdb=# SELECT relname, reltuples FROM PG_CLASS gaussdb-# WHERE relname='t1' gaussdb-# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_table'); relname | reltuples ---------+----------- t1 | 6 (1 row) gaussdb=# -- 回退到最早的统计信息 gaussdb=# CALL DBE_STATS.RESTORE_TABLE_STATS( gaussdb(# ownname=>'dbe_stats_restore_table', gaussdb(# tabname=>'t1', gaussdb(# as_of_timestamp=>(SELECT MIN(reltimestamp) FROM GS_TABLESTATS_HISTORY WHERE relname='t1' gaussdb(# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_table')) gaussdb(# ); restore_table_stats --------------------- (1 row) gaussdb=# -- 验证: 回退后 reltuples=3 gaussdb=# SELECT relname, reltuples FROM PG_CLASS gaussdb-# WHERE relname='t1' gaussdb-# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_table'); relname | reltuples ---------+----------- t1 | 3 (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_restore_table; DROP SCHEMA
- DBE_STATS.RESTORE_PARTITION_STATS
将分区的统计信息回退到指定的时间节点,选择该时间节点前最后一次收集的统计信息载入系统表,同时级联其下级未被锁定的分区、索引、列级统计信息。该接口无返回值。
DBE_STATS.RESTORE_PARTITION_STATS原型为:
DBE_STATS.RESTORE_PARTITION_STATS( ownname VARCHAR2, tabname VARCHAR2, partname VARCHAR2, as_of_timestamp TIMESTAMPTZ, force BOOLEAN DEFAULT FALSE, no_invalidate BOOLEAN DEFAULT NULL );表11 DBE_STATS.RESTORE_PARTITION_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
是
要回退的分区所属的Schema名称。
tabname
VARCHAR2
否
要回退的分区所属的表名。
partname
VARCHAR2
否
要回退的分区名。
as_of_timestamp
timestamp with time zone
否
要回退的目标时间节点。
force
BOOLEAN
是
是否在统计信息被锁定时强行回退的标志位。
no_invalidate
BOOLEAN
是
暂不支持。
- 调用该接口时,同时回退其下级分区、索引、列的统计信息。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_restore_partition CASCADE; NOTICE: schema "dbe_stats_restore_partition" does not exist, skipping DROP SCHEMA gaussdb=# -- 建分区表,收集两次分区统计信息 gaussdb=# CREATE SCHEMA dbe_stats_restore_partition; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_restore_partition; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication PARTITION BY RANGE(a) gaussdb-# ( gaussdb(# PARTITION p1 VALUES LESS THAN(10), gaussdb(# PARTITION p2 VALUES LESS THAN(MAXVALUE) gaussdb(# ); CREATE TABLE gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# ANALYZE t1 PARTITION (p1); ANALYZE gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# ANALYZE t1 PARTITION (p1); ANALYZE gaussdb=# -- 查看历史表 (应有分区的历史记录) gaussdb=# SELECT relname, relkind, reltuples FROM GS_TABLESTATS_HISTORY gaussdb-# WHERE relname='p1' AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_partition') gaussdb-# ORDER BY reltuples; relname | relkind | reltuples ---------+---------+----------- p1 | p | 3 p1 | p | 6 (2 rows) gaussdb=# -- 查看当前分区统计信息 (reltuples=6) gaussdb=# SELECT relname, reltuples FROM PG_PARTITION gaussdb-# WHERE relname='p1' AND parentid = (SELECT oid FROM PG_CLASS WHERE relname='t1' AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_partition')); relname | reltuples ---------+----------- p1 | 6 (1 row) gaussdb=# -- 回退分区p1到最早的统计信息 gaussdb=# CALL DBE_STATS.RESTORE_PARTITION_STATS( gaussdb(# ownname=>'dbe_stats_restore_partition', gaussdb(# tabname=>'t1', gaussdb(# partname=>'p1', gaussdb(# as_of_timestamp=>(SELECT MIN(reltimestamp) FROM GS_TABLESTATS_HISTORY WHERE relname='p1' AND gaussdb(# relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_partition')) gaussdb(# ); restore_partition_stats ------------------------- (1 row) gaussdb=# -- 验证回退结果 (reltuples应回退到3) gaussdb=# SELECT relname, reltuples FROM PG_PARTITION gaussdb-# WHERE relname='p1' AND parentid = (SELECT oid FROM PG_CLASS WHERE relname='t1' AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_partition')); relname | reltuples ---------+----------- p1 | 3 (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_restore_partition; DROP SCHEMA
- DBE_STATS.RESTORE_COLUMN_STATS
将列的统计信息回退到指定的时间节点,选择该时间节点前最后一次收集的统计信息载入系统表。该接口无返回值。
DBE_STATS.RESTORE_COLUMN_STATS原型为:
DBE_STATS.RESTORE_COLUMN_STATS( ownname VARCHAR2, tabname VARCHAR2, colname VARCHAR2, partname VARCHAR2 DEFAULT NULL, as_of_timestamp TIMESTAMPTZ, force BOOLEAN DEFAULT FALSE, no_invalidate BOOLEAN DEFAULT NULL );表12 DBE_STATS.RESTORE_COLUMN_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
是
要回退的列所属的Schema名。
tabname
VARCHAR2
否
要回退的列所属的表名。
colname
VARCHAR2
否
要回退的列名。
partname
VARCHAR2
是
要回退的列所属的分区名。
as_of_timestamp
timestamp with time zone
否
要回退的目标时间节点。
force
BOOLEAN
是
是否在统计信息被锁定时强行回退的标志位。
no_invalidate
BOOLEAN
是
暂不支持。
- 当partname为空时,默认回退该列表及统计信息。
- 回退多列时,需先查询PG_STATISTIC_EXT中的staextname字段,获取多列别名作为colname参数传入。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_restore_column CASCADE; NOTICE: schema "dbe_stats_restore_column" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集两次统计信息 gaussdb=# CREATE SCHEMA dbe_stats_restore_column; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_restore_column; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 确保两次ANALYZE时间戳间隔>1秒 gaussdb=# SELECT pg_sleep(1.1); pg_sleep ---------- (1 row) gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 查看历史表里的统计信息 gaussdb=# SELECT staattnum, stadistinct, stakind1, stanumbers1, stavalues1 gaussdb-# FROM GS_STATISTIC_HISTORY gaussdb-# WHERE starelid='t1'::REGCLASS gaussdb-# ORDER BY statimestamp; staattnum | stadistinct | stakind1 | stanumbers1 | stavalues1 -----------+-------------+----------+-------------+------------ 1 | -.333333 | 1 | {1} | {1} 2 | -.333333 | 1 | {1} | {1} 1 | -.333333 | 1 | {.5,.5} | {1,2} 2 | -.333333 | 1 | {.5,.5} | {1,2} (4 rows) gaussdb=# SELECT staattnum, stadistinct, stakind1, stanumbers1, stavalues1 gaussdb-# FROM PG_STATISTIC gaussdb-# WHERE starelid='t1'::REGCLASS gaussdb-# ORDER BY 1; staattnum | stadistinct | stakind1 | stanumbers1 | stavalues1 -----------+-------------+----------+-------------+------------ 1 | -.333333 | 1 | {.5,.5} | {1,2} 2 | -.333333 | 1 | {.5,.5} | {1,2} (2 rows) gaussdb=# -- 回退列a到时间较早的时间节点 gaussdb=# CALL DBE_STATS.RESTORE_COLUMN_STATS( gaussdb(# ownname=>'dbe_stats_restore_column', gaussdb(# tabname=>'t1', gaussdb(# colname=>'a', gaussdb(# as_of_timestamp=>((SELECT MIN(reltimestamp) FROM GS_TABLESTATS_HISTORY WHERE relname='t1' gaussdb(# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_column')) + INTERVAL '1 second') gaussdb(# ); restore_column_stats ---------------------- (1 row) gaussdb=# -- 验证回退后列a的统计信息 (stanumbers1={1}, stavalues1={1}) gaussdb=# SELECT staattnum, stadistinct, stakind1, stanumbers1, stavalues1 gaussdb-# FROM PG_STATISTIC gaussdb-# WHERE starelid='t1'::REGCLASS gaussdb-# ORDER BY 1; staattnum | stadistinct | stakind1 | stanumbers1 | stavalues1 -----------+-------------+----------+-------------+------------ 1 | -.333333 | 1 | {1} | {1} 2 | -.333333 | 1 | {.5,.5} | {1,2} (2 rows) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_restore_column; DROP SCHEMA - DBE_STATS.RESTORE_SCHEMA_STATS
将指定schema下所有表的统计信息回退到指定时间节点。该接口无返回值。
DBE_STATS.RESTORE_SCHEMA_STATS原型为:
DBE_STATS.RESTORE_SCHEMA_STATS( ownname VARCHAR2, as_of_timestamp TIMESTAMPTZ, force BOOLEAN DEFAULT FALSE, no_invalidate BOOLEAN DEFAULT NULL );表13 DBE_STATS.RESTORE_SCHEMA_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
是
指定的Schema名称。
as_of_timestamp
timestamp with time zone
否
要回退的目标时间节点。
force
BOOLEAN
是
是否在统计信息被锁定时强行回退的标志位。
no_invalidate
BOOLEAN
是
暂不支持。
当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_restore_schema CASCADE; NOTICE: schema "dbe_stats_restore_schema" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,插数据,收集两次统计信息 gaussdb=# CREATE SCHEMA dbe_stats_restore_schema; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_restore_schema; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 查看历史表 gaussdb=# SELECT relname, reltuples FROM GS_TABLESTATS_HISTORY WHERE relid='t1'::regclass ORDER BY 1, 2; relname | reltuples ---------+----------- t1 | 3 t1 | 6 (2 rows) gaussdb=# -- 查看当前系统表 (reltuples=6) gaussdb=# SELECT relname, reltuples FROM PG_CLASS gaussdb-# WHERE relname='t1' gaussdb-# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_schema'); relname | reltuples ---------+----------- t1 | 6 (1 row) gaussdb=# -- 回退schema gaussdb=# CALL DBE_STATS.RESTORE_SCHEMA_STATS( gaussdb(# ownname=>'dbe_stats_restore_schema', gaussdb(# as_of_timestamp=>(SELECT MIN(reltimestamp) FROM GS_TABLESTATS_HISTORY WHERE relname='t1' gaussdb(# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_schema')) gaussdb(# ); restore_schema_stats ---------------------- (1 row) gaussdb=# -- 验证: 回退后 reltuples=3 gaussdb=# SELECT relname, reltuples FROM PG_CLASS gaussdb-# WHERE relname='t1' gaussdb-# AND relnamespace = (SELECT oid FROM PG_NAMESPACE WHERE nspname='dbe_stats_restore_schema'); relname | reltuples ---------+----------- t1 | 3 (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_restore_schema; DROP SCHEMA
- DBE_STATS.PURGE_STATS
DBE_STATS.PURGE_STATS原型为:
DBE_STATS.PURGE_STATS( before_timestamp TIMESTAMPTZ );表14 DBE_STATS.PURGE_STATS接口参数说明 参数
类型
是否允许为空
描述
before_timestamp
timestamp with time zone
否
指定要清除的时间节点。
示例:
-- 建表,收集两次统计信息。 gaussdb=# CREATE SCHEMA dbe_stats_purge; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA=dbe_stats_purge; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(1,1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES(2,2); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE -- 查看历史表。 gaussdb=# SELECT relname,reltuples FROM GS_TABLESTATS_HISTORY WHERE relname='t1' ORDER BY 1,2; relname | reltuples ---------+----------- t1 | 3 t1 | 6 (2 rows) -- 清除时间较早的历史统计信息,查看历史表。 gaussdb=# CALL DBE_STATS.PURGE_STATS(before_timestamp=>((SELECT MIN(reltimestamp) FROM GS_TABLESTATS_HISTORY WHERE relname='t1') + INTERVAL '1 second')); purge_stats ------------- (1 row) gaussdb=# SELECT relname,reltuples FROM GS_TABLESTATS_HISTORY WHERE relname='t1'; relname | reltuples ---------+----------- t1 | 6 (1 row) -- 删除表、命名空间。 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_purge; DROP SCHEMA
- DBE_STATS.GET_STATS_HISTORY_RETENTION
获得当前历史统计信息的保留时间,返回用GUC参数stats_history_retention_time的值,表示历史统计信息的保留时间。该接口没有入参。
DBE_STATS.GET_STATS_HISTORY_RETENTION原型为:
DBE_STATS.GET_STATS_HISTORY_RETENTION() returns NUMBER;
示例:
gaussdb=# CALL DBE_STATS.GET_STATS_HISTORY_RETENTION(); get_stats_history_retention ----------------------------- 31 (1 row) - DBE_STATS.GET_STATS_HISTORY_AVAILABILITY
获得当前历史统计信息的最早可用时间,返回当前数据库下所有历史统计信息的最早时间。该接口没有入参。
DBE_STATS.GET_STATS_HISTORY_AVAILABILITY原型为:
DBE_STATS.GET_STATS_HISTORY_AVAILABILITY() returns TIMESTAMPTZ;
示例:
gaussdb=# ANALYZE; ANALYZE gaussdb=# CALL DBE_STATS.GET_STATS_HISTORY_AVAILABILITY(); get_stats_history_availability -------------------------------- 2025-05-07 05:11:43.584349-04 (1 row)
DBE_STATS高级包接口仅对普通表有效。
- DBE_STATS.CREATE_STAT_TABLE
DBE_STATS.CREATE_STAT_TABLE原型为:
DBE_STATS.CREATE_STAT_TABLE ( ownname VARCHAR2, stattab VARCHAR2, tblspace VARCHAR2 DEFAULT NULL, global_temporary BOOLEAN DEFAULT NULL );表15 DBE_STATS.CREATE_STAT_TABLE接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
指定创建的统计表所在的Schema。如果设置为null,默认在当前所在的Schema创建。
stattab
VARCHAR2
否
统计表的名称。
tblspace
VARCHAR2
是
指定创建的统计表所在的表空间。如果不指定,则使用默认表空间进行创建。
global_temporary
BOOLEAN
是
暂不支持该参数。
- 为了区分普通表和统计表,在创建统计表后,其reloptions中的字段statstable将不为空串。且考虑到统计表结构可能进行版本升级,为实现前向兼容,statstable将被赋予当前统计信息表的版本信息。
- 该表创建时会自动生成一个索引gs_stattab_<name_hash_value>_statid_type_nameinfo_index用于索引扫描,其中<name_hash_value>为该统计信息表名的哈希值。如若被删除,则导入导出export、import接口不可用。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
-- 在dbe_stats_create_drop_schema下创建一个stattab统计表,并手动插入一条数据,可从新建的用户统计信息表中查询到此条数据。 gaussdb=# CREATE SCHEMA dbe_stats_create_drop_schema; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_create_drop_schema; SET gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE(ownname => 'dbe_stats_create_drop_schema', stattab => 'stat_tab'); create_stat_table ------------------- (1 row) gaussdb=# INSERT INTO stat_tab(nodeid, statid, type, relname) VALUES(0, '123', 't', 't1'); INSERT 0 1 gaussdb=# SELECT statid, type, relname FROM stat_tab; statid | type | relname --------+------+--------- 123 | t | t1 (1 row)
- DBE_STATS.DROP_STAT_TABLE
DBE_STATS.DROP_STAT_TABLE原型为:
DBE_STATS.DROP_STAT_TABLE ( ownname VARCHAR2, stattab VARCHAR2 );表16 DBE_STATS.DROP_STAT_TABLE接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
统计表所在的Schema。如果设置为null,则默认使用当前Schema。
stattab
VARCHAR2
否
统计表的名称。
- 对于statstable属性为空的普通表,无法使用此函数删除。
- 如果在用户统计信息表上已创建索引或者已创建其他依赖于该表的对象,则在调用此函数时,将级联删除所有依赖于该表的对象。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
-- 删除用户统计信息表。将上述所建的用户统计信息表删除,删除新建的Schema。 gaussdb=# CALL DBE_STATS.DROP_STAT_TABLE(ownname => 'dbe_stats_create_drop_schema', stattab => 'stat_tab'); drop_stat_table ----------------- (1 row) gaussdb=# DROP SCHEMA dbe_stats_create_drop_schema CASCADE; DROP SCHEMA
- DBE_STATS.EXPORT_INDEX_STATS
在系统表中查找指定索引的统计信息,并将结果存储在用户统计信息表中。该接口无返回值。
DBE_STATS.EXPORT_INDEX_STATS原型为:
DBE_STATS.EXPORT_INDEX_STATS ( ownname VARCHAR2, indname VARCHAR2, partname VARCHAR2 DEFAULT NULL, stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, statown VARCHAR2 DEFAULT NULL );表17 DBE_STATS.EXPORT_INDEX_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
指定索引所在Schema的名称,如果设置为null,会默认使用当前的Schema。
indname
VARCHAR2
否
指定需要导出统计信息的索引名。
partname
VARCHAR2
是
分区索引的名称。如果索引已分区但是partname为null,则导出全局和分区索引统计信息。
stattab
VARCHAR2
否
指定存储统计信息用户表的表名。
statid
VARCHAR2
是
指向stattab中统计信息的标识符(可选)。
statown
VARCHAR2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用ownname参数的值。
- 导出索引的reltuples(numrows)、relpages(numlblks)和relallvisible(relallvisible)三类统计信息。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
-- 建表,收集统计信息。 gaussdb=# CREATE SCHEMA dbe_stats_export; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_export; SET gaussdb=# CREATE TABLE t2(a int, b int, c int) distribute by replication PARTITION BY RANGE(a) SUBPARTITION BY RANGE(b) ( PARTITION p1 VALUES LESS THAN(200) (SUBPARTITION s1 VALUES LESS THAN (500), SUBPARTITION s2 VALUES LESS THAN (MAXVALUE) ), PARTITION p2 VALUES LESS THAN(500) (SUBPARTITION s3 VALUES LESS THAN (500), SUBPARTITION s4 VALUES LESS THAN (MAXVALUE) ), PARTITION p3 VALUES LESS THAN(MAXVALUE) ( SUBPARTITION s5 VALUES LESS THAN (500), SUBPARTITION s6 VALUES LESS THAN (MAXVALUE) ) ); CREATE TABLE gaussdb=# CREATE INDEX idx_t2_local_a ON t2(a) LOCAL ( PARTITION p1_idx_a ( SUBPARTITION s1_idx_a, SUBPARTITION s2_idx_a ), PARTITION p2_idx_a ( SUBPARTITION s3_idx_a, SUBPARTITION s4_idx_a ), PARTITION p3_idx_a ( SUBPARTITION s5_idx_a, SUBPARTITION s6_idx_a )); CREATE INDEX gaussdb=# INSERT INTO t2 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (100, 600, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (300, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (300, 600, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (600, 400, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (600, 600, 1); INSERT 0 1 gaussdb=# ANALYZE t2 WITH ALL; ANALYZE gaussdb=# ANALYZE t2((a,b)) WITH ALL; ANALYZE -- 建立用户统计信息表,作为统计信息导出的目标表。 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_export', 'export_table'); create_stat_table ------------------- (1 row) -- 导出索引统计信息,连同分区索引的统计信息一并导出。 -- 查看当前的统计信息。 gaussdb=# SELECT reltuples FROM PG_CLASS WHERE relname='idx_t2_local_a'; reltuples ----------- 6 (1 row) gaussdb=# SELECT relname,relpages,reltuples FROM PG_PARTITION WHERE parentid='idx_t2_local_a'::REGCLASS ORDER BY oid; relname | relpages | reltuples ----------+----------+----------- s1_idx_a | 1 | 0 s2_idx_a | 1 | 0 s3_idx_a | 1 | 0 s4_idx_a | 1 | 0 s5_idx_a | 1 | 0 s6_idx_a | 1 | 0 (6 rows) -- 导出统计信息,查看用户统计信息表中的数据。 gaussdb=# CALL DBE_STATS.EXPORT_INDEX_STATS(ownname => 'dbe_stats_export', indname => 'idx_t2_local_a', partname=> null, stattab => 'export_table', statid => 'idx_s1'); export_index_stats -------------------- (1 row) gaussdb=# SELECT relname,partname,numrows,numblocks FROM export_table WHERE nodeid = 1 ORDER BY relname, partname desc; relname | partname | numrows | numblocks ----------------+----------+---------+----------- idx_t2_local_a | | 6 | 6 idx_t2_local_a | s6_idx_a | 0 | 1 idx_t2_local_a | s5_idx_a | 0 | 1 idx_t2_local_a | s4_idx_a | 0 | 1 idx_t2_local_a | s3_idx_a | 0 | 1 idx_t2_local_a | s2_idx_a | 0 | 1 idx_t2_local_a | s1_idx_a | 0 | 1 (7 rows) -- 删除表、命名空间。 gaussdb=# DROP INDEX idx_t2_local_a; DROP INDEX gaussdb=# DROP TABLE t2; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_export; DROP SCHEMA
- DBE_STATS.EXPORT_TABLE_STATS
检索指定表的统计信息,并存储在用户统计信息表中。该接口无返回值。
DBE_STATS.EXPORT_TABLE_STATS原型为:
DBE_STATS.EXPORT_TABLE_STATS ( ownname VARCHAR2, tabname VARCHAR2, partname VARCHAR2 DEFAULT NULL, stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, cascade BOOLEAN DEFAULT TRUE, statown VARCHAR2 DEFAULT NULL, stat_category VARCHAR2 DEFAULT NULL );
表18 DBE_STATS.EXPORT_TABLE_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
指定Schema的名称,如果设置为null,会默认使用当前的Schema。
tabname
VARCHAR2
否
指定需要导出统计信息的表名。
partname
VARCHAR2
是
表分区的名称。如果表已分区但是partname为null,则导出全局和分区表统计信息。
stattab
VARCHAR2
否
指定存储统计信息用户表的表名。
statid
VARCHAR2
是
指向stattab中统计信息的标识符(可选)。
cascade
BOOLEAN
是
是否一并导出列、索引、多列和索引表达式的统计信息。默认为TRUE。
statown
VARCHAR2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用ownname参数的值。
stat_category
VARCHAR2
是
暂不支持。
- 导出表的reltuples(numrows)、relpages(numblks)和relallvisible(relallvisible)三类统计信息。级联导出列级、索引级的统计信息参考EXPORT_INDEX_STATS和EXPORT_COLUMN_STATS接口的统计信息。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_export_table CASCADE; NOTICE: schema "dbe_stats_export_table" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集统计信息 gaussdb=# CREATE SCHEMA dbe_stats_export_table; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_export_table; SET gaussdb=# CREATE TABLE t1(a int, b int, c int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (150, 550, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 建立用户统计信息表 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_export_table', 'export_table'); create_stat_table ------------------- (1 row) gaussdb=# -- 导出表统计信息 (级联导出列、索引统计信息) gaussdb=# CALL DBE_STATS.EXPORT_TABLE_STATS( gaussdb(# ownname => 'dbe_stats_export_table', gaussdb(# tabname => 't1', gaussdb(# partname => null, gaussdb(# stattab => 'export_table', gaussdb(# statid => 't1_t', gaussdb(# cascade => true gaussdb(# ); export_table_stats -------------------- (1 row) gaussdb=# -- 验证: 用户统计信息表中应有数据 gaussdb=# SELECT count(*) AS row_count FROM export_table WHERE relname='t1' and nodeid=0; row_count ----------- 4 (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_export_table; DROP SCHEMA
- DBE_STATS.EXPORT_COLUMN_STATS
检索指定列(多列/表达式)的统计信息并存储在用户统计信息表中。该接口无返回值。
DBE_STATS.EXPORT_COLUMN_STATS原型为:
DBE_STATS.EXPORT_COLUMN_STATS ( ownname VARCHAR2, tabname VARCHAR2, colname VARCHAR2, partname VARCHAR2 DEFAULT NULL, stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, statown VARCHAR2 DEFAULT NULL );
表19 DBE_STATS.EXPORT_COLUMN_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
指定Schema的名称,如果设置为null,会默认使用当前的Schema。
tabname
VARCHAR2
否
指定需要导出统计信息的列所属的表名(表达式对应索引名)。
colname
VARCHAR2
否
列名或者多列名(tabname为索引时,colname为表达式名)。
partname
VARCHAR2
是
分区的名称。如果表/索引已分区但是partname为null,则导出全局和分区列/多列/索引表达式统计信息。
stattab
VARCHAR2
否
指定存储统计信息用户表的表名。
statid
VARCHAR2
是
指向stattab中统计信息的标识符(可选)。
statown
VARCHAR2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用ownname参数的值。
- 导出列级的统计信息可查询PG_STATISTIC和PG_STATISTIC_EXT。
- 导出多列统计信息时,需先查询PG_STATISTIC_EXT中的staextname字段,获取多列别名作为colname参数传入。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
-- 建表,收集统计信息。 gaussdb=# CREATE SCHEMA dbe_stats_export; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA=dbe_stats_export; SET gaussdb=# CREATE TABLE IF NOT EXISTS t1 (a int, b int, c int) distribute by replication; CREATE TABLE gaussdb=# CREATE INDEX idx_t1_expr on t1((a*a), (a+a), (a*b)); CREATE INDEX gaussdb=# INSERT INTO t1 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (150, 550, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# ANALYZE t1((a,b)); ANALYZE -- 建立用户统计信息表。 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_export', 'export_table'); create_stat_table ------------------- (1 row) -- 查看列级统计信息。 gaussdb=# SELECT staattnum,stadistinct,stakind1,stanumbers1,stavalues1 FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS ORDER BY 1; staattnum | stadistinct | stakind1 | stanumbers1 | stavalues1 -----------+-------------+----------+-------------+--------------- 1 | -1 | 2 | | {100,150,250} 2 | -1 | 2 | | {150,300,550} 3 | -.333333 | 1 | {1} | {1} (3 rows) -- 导出列级统计信息,查看用户统计信息表。 gaussdb=# CALL DBE_STATS.EXPORT_COLUMN_STATS(ownname => 'dbe_stats_export', tabname => 't1', colname=> 'a', partname => null, stattab => 'export_table', statid => 't1_c'); export_column_stats --------------------- (1 row) gaussdb=# SELECT relname,columnname,stadistinct,stakind1,stanumbers1,stavalues1 FROM export_table WHERE nodeid=0; relname | columnname | stadistinct | stakind1 | stanumbers1 | stavalues1 ---------+------------+-------------+----------+-------------+--------------- t1 | a | -1 | 2 | | {100,150,250} (1 row) -- 查看表达式统计信息。 gaussdb=# SELECT staattnum,stadistinct,stakind1,stanumbers1,stavalues1 FROM PG_STATISTIC WHERE starelid='idx_t1_expr'::REGCLASS ORDER BY 1; staattnum | stadistinct | stakind1 | stanumbers1 | stavalues1 -----------+-------------+----------+-------------+--------------------- 1 | -1 | 2 | | {10000,22500,62500} 2 | -1 | 2 | | {200,300,500} 3 | -1 | 2 | | {30000,37500,82500} (3 rows) -- 导出表达式统计信息,查看用户统计信息表。 gaussdb=# CALL DBE_STATS.EXPORT_COLUMN_STATS(ownname => 'dbe_stats_export', tabname => 'idx_t1_expr', colname => 'expr', stattab => 'export_table', statid => 't1_expr'); export_column_stats --------------------- (1 row) gaussdb=# SELECT relname,columnname,stadistinct,stakind1,stanumbers1,stavalues1 FROM export_table where statid='t1_expr' AND nodeid=0; relname | columnname | stadistinct | stakind1 | stanumbers1 | stavalues1 -------------+------------+-------------+----------+-------------+--------------------- idx_t1_expr | expr | -1 | 2 | | {10000,22500,62500} (1 row) -- 导出多列统计信息。 -- 查看多列统计信息。 gaussdb=# SELECT stakey,staextname,stadistinct,stakind1,stanumbers1,stavalues1 FROM PG_STATISTIC_EXT WHERE starelid='t1'::REGCLASS; stakey | staextname | stadistinct | stakind1 | stanumbers1 | stavalues1 --------+---------------------+-------------+----------+-------------+------------ 1 2 | extname_-1308656218 | -1 | 8 | | (1 row) -- 导出,查看用户统计信息表。 gaussdb=# CALL DBE_STATS.EXPORT_COLUMN_STATS(ownname => 'dbe_stats_export', tabname => 't1', colname=> 'extname_-1308656218', partname => null, stattab => 'export_table', statid => 't1_c'); export_column_stats --------------------- (1 row) gaussdb=# SELECT relname,columnname,stadistinct,stakind1,stanumbers1,stavalues1 FROM export_table WHERE nodeid=0 AND relname='t1'; relname | columnname | stadistinct | stakind1 | stanumbers1 | stavalues1 ---------+---------------------+-------------+----------+-------------+--------------- t1 | a | -1 | 2 | | {100,150,250} t1 | extname_-1308656218 | -1 | 8 | | (2 rows) -- 删除表、命名空间。 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_export; DROP SCHEMA
- DBE_STATS.EXPORT_SCHEMA_STATS
用于检索指定Schema的统计信息,并存储在用户统计信息表中。该接口无返回值。
DBE_STATS.EXPORT_SCHEMA_STATS原型为:
DBE_STATS.EXPORT_SCHEMA_STATS ( ownname VARCHAR2, stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, statown VARCHAR2 DEFAULT NULL, stat_category VARCHAR2 DEFAULT NULL );
表20 DBE_STATS.EXPORT_SCHEMA_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
指定Schema的名称,如果设置为null,会默认使用当前的Schema。
stattab
VARCHAR2
否
指定存储统计信息用户表的表名。
statid
VARCHAR2
是
指向stattab中统计信息的标识符(可选)。
statown
VARCHAR2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用ownname参数的值。
stat_category
VARCHAR2
是
暂不支持。
- 导出当前用户在指定Schema下所有具有权限的表的统计信息,对于无权限的表直接跳过,不报错。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_export_schema CASCADE; NOTICE: schema "dbe_stats_export_schema" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集统计信息 gaussdb=# CREATE SCHEMA dbe_stats_export_schema; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_export_schema; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES (1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (2,2); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 建立用户统计信息表 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_export_schema', 'export_table'); create_stat_table ------------------- (1 row) gaussdb=# -- 导出schema统计信息 gaussdb=# CALL DBE_STATS.EXPORT_SCHEMA_STATS( gaussdb(# ownname => 'dbe_stats_export_schema', gaussdb(# stattab => 'export_table', gaussdb(# statid => 's1' gaussdb(# ); export_schema_stats --------------------- (1 row) gaussdb=# -- 验证: 用户统计信息表中应有数据 gaussdb=# SELECT relname,numrows FROM export_table where nodeid=0 and numrows != 0; relname | numrows ---------+--------- t1 | 2 (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_export_schema; DROP SCHEMA
- DBE_STATS.EXPORT_DATABASE_STATS
用于检索指定database的统计信息,并存储在用户统计信息表中。该接口无返回值。
DBE_STATS.EXPORT_DATABASE_STATS原型:
DBE_STATS.EXPORT_DATABASE_STATS ( stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, statown VARCHAR2 DEFAULT NULL, stat_category VARCHAR2 DEFAULT NULL );
表21 DBE_STATS.EXPORT_DATABASE_STATS接口参数说明 参数
类型
是否允许为空
描述
stattab
VARCHAR2
否
指定存储统计信息用户表的表名。
statid
VARCHAR2
是
指向stattab中统计信息的标识符(可选)。
statown
VARCHAR2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用当前Schema。
stat_category
VARCHAR2
是
暂不支持。
- 导出当前用户在当前database下所有具有analyze权限用户表的统计信息,对于无权限的表直接跳过,不报错。
- 当statown参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_export_database CASCADE; NOTICE: schema "dbe_stats_export_database" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集统计信息 gaussdb=# CREATE SCHEMA dbe_stats_export_database; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_export_database; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES (1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (2,2); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 建立用户统计信息表 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_export_database', 'export_table'); create_stat_table ------------------- (1 row) gaussdb=# -- 导出database统计信息 gaussdb=# CALL DBE_STATS.EXPORT_DATABASE_STATS( gaussdb(# statown => 'dbe_stats_export_database', gaussdb(# stattab => 'export_table', gaussdb(# statid => 's1' gaussdb(# ); export_database_stats ----------------------- (1 row) gaussdb=# -- 验证: 用户统计信息表中应有数据 gaussdb=# SELECT count(*) > 0 FROM export_table; ?column? ---------- t (1 row) gaussdb=# SELECT count(*) > 0 FROM export_table WHERE relname='t1'; ?column? ---------- t (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_export_database; DROP SCHEMA - DBE_STATS.IMPORT_INDEX_STATS
从stattab标识的用户统计信息表中检索指定索引的统计信息,并将其写回系统表中。该接口无返回值。
DBE_STATS.IMPORT_INDEX_STATS原型为:
DBE_STATS.IMPORT_INDEX_STATS ( ownname VARCHAR2, indname VARCHAR2, partname VARCHAR2 DEFAULT NULL, stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, statown VARCHAR2 DEFAULT NULL, no_invalidate BOOLEAN DEFAULT NULL, force BOOLEAN DEFAULT FALSE );
表22 DBE_STATS.IMPORT_INDEX_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
指定Schema的名称,如果设置为null,会默认使用当前的Schema。
indname
VARCHAR2
否
指定需要导入统计信息的索引名。
partname
VARCHAR2
是
索引分区的名称。如果索引已分区但是partname为null,则导入全局和分区索引统计信息。
stattab
VARCHAR2
否
指定存储统计信息用户表的表名。
statid
VARCHAR2
是
指向stattab中统计信息的标识符(可选)。
statown
VARCHAR2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用ownname参数的值。
no_invalidate
BOOLEAN
是
暂不支持。
force
BOOLEAN
是
是否强制导入,忽略锁的状态,默认false。
- 导入索引的reltuples(numrows)、relpages(numlblks)和relallvisible(relallvisible)三类统计信息。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
-- 建表,收集统计信息。 gaussdb=# CREATE SCHEMA dbe_stats_import; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_import; SET gaussdb=# CREATE TABLE t2(a int, b int, c int)distribute by replication PARTITION BY RANGE(a) SUBPARTITION BY RANGE(b) ( PARTITION p1 VALUES LESS THAN(200) (SUBPARTITION s1 VALUES LESS THAN (500), SUBPARTITION s2 VALUES LESS THAN (MAXVALUE) ), PARTITION p2 VALUES LESS THAN(500) (SUBPARTITION s3 VALUES LESS THAN (500), SUBPARTITION s4 VALUES LESS THAN (MAXVALUE) ), PARTITION p3 VALUES LESS THAN(MAXVALUE) ( SUBPARTITION s5 VALUES LESS THAN (500), SUBPARTITION s6 VALUES LESS THAN (MAXVALUE) ) ); CREATE TABLE gaussdb=# CREATE INDEX idx_t2_local_a ON t2(a) LOCAL ( PARTITION p1_idx_a ( SUBPARTITION s1_idx_a, SUBPARTITION s2_idx_a ), PARTITION p2_idx_a ( SUBPARTITION s3_idx_a, SUBPARTITION s4_idx_a ), PARTITION p3_idx_a ( SUBPARTITION s5_idx_a, SUBPARTITION s6_idx_a )); CREATE INDEX gaussdb=# INSERT INTO t2 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (100, 600, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (300, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (300, 600, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (600, 400, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (600, 600, 1); INSERT 0 1 gaussdb=# ANALYZE t2 WITH ALL; ANALYZE -- 创建用户统计信息表,先将数据导出。 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_import', 'export_table'); create_stat_table ------------------- (1 row) gaussdb=# CALL DBE_STATS.EXPORT_INDEX_STATS(ownname => 'dbe_stats_import', indname => 'idx_t2_local_a', partname=> null, stattab => 'export_table', statid => 'idx_s1'); export_index_stats -------------------- (1 row) gaussdb=# SELECT relname,partname,numrows,numblocks FROM export_table WHERE nodeid=1 ORDER BY relname,partname desc; relname | partname | numrows | numblocks ----------------+----------+---------+----------- idx_t2_local_a | | 6 | 6 idx_t2_local_a | s6_idx_a | 0 | 1 idx_t2_local_a | s5_idx_a | 0 | 1 idx_t2_local_a | s4_idx_a | 0 | 1 idx_t2_local_a | s3_idx_a | 0 | 1 idx_t2_local_a | s2_idx_a | 0 | 1 idx_t2_local_a | s1_idx_a | 0 | 1 (7 rows) -- 再次插入数据,收集统计信息,查看统计信息。 gaussdb=# INSERT INTO t2 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (100, 600, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (100, 600, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (300, 600, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (600, 400, 1); INSERT 0 1 gaussdb=# INSERT INTO t2 VALUES (600, 600, 1); INSERT 0 1 gaussdb=# ANALYZE t2 WITH ALL; ANALYZE gaussdb=# SELECT reltuples FROM PG_CLASS WHERE relname='idx_t2_local_a'; reltuples ----------- 12 (1 row) gaussdb=# SELECT relname,relpages,reltuples FROM PG_PARTITION WHERE parentid='idx_t2_local_a'::REGCLASS ORDER BY oid; relname | relpages | reltuples ----------+----------+----------- s1_idx_a | 1 | 0 s2_idx_a | 1 | 0 s3_idx_a | 1 | 0 s4_idx_a | 1 | 0 s5_idx_a | 1 | 0 s6_idx_a | 1 | 0 (6 rows) -- 将用户统计表中的统计信息导入统计信息系统表。 gaussdb=# CALL DBE_STATS.IMPORT_INDEX_STATS(ownname => 'dbe_stats_import', indname => 'idx_t2_local_a', stattab => 'export_table', statid => 'idx_s1'); import_index_stats -------------------- (1 row) gaussdb=# SELECT reltuples FROM PG_CLASS WHERE relname='idx_t2_local_a'; reltuples ----------- 6 (1 row) gaussdb=# SELECT relname,relpages,reltuples FROM PG_PARTITION WHERE parentid='idx_t2_local_a'::REGCLASS ORDER BY oid; relname | relpages | reltuples ----------+----------+----------- s1_idx_a | 1 | 0 s2_idx_a | 1 | 0 s3_idx_a | 1 | 0 s4_idx_a | 1 | 0 s5_idx_a | 1 | 0 s6_idx_a | 1 | 0 (6 rows) -- 删除表、命名空间。 gaussdb=# DROP TABLE t2; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_import; DROP SCHEMA
- DBE_STATS.IMPORT_TABLE_STATS
从stattab标识的用户统计信息表中检索指定表的统计信息,并将其写回系统表中。该接口无返回值。
DBE_STATS.IMPORT_TABLE_STATS原型为:
DBE_STATS.IMPORT_TABLE_STATS ( ownname VARCHAR2, tabname VARCHAR2, partname VARCHAR2 DEFAULT NULL, stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, cascade BOOLEAN DEFAULT TRUE, statown VARCHAR2 DEFAULT NULL, no_invalidate BOOLEAN DEFAULT NULL, force BOOLEAN DEFAULT FALSE, stat_category VARCHAR2 DEFAULT NULL );
表23 DBE_STATS.IMPORT_TABLE_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
varchar2
否
指定Schema的名称,如果设置为null,会默认使用当前的Schema。
tabname
varchar2
否
指定需要导入统计信息的表名。
partname
varchar2
是
表分区的名称。如果表已分区但是partname为null,则导入全局和分区表统计信息。
stattab
varchar2
否
指定存储统计信息用户表的表名。
statid
varchar2
是
指向stattab中统计信息的标识符(可选)。
cascade
boolean
是
是否一并导入列、索引、多列和索引表达式的统计信息。默认为true。
statown
varchar2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用ownname参数的值。
no_invalidate
boolean
是
暂不支持。
force
boolean
是
是否强制导入,忽略锁的状态,默认false。
stat_category
varchar2
是
暂不支持。
- 导入表的reltuples(numrows)、relpages(numblks)和relallvisible(relallvisible)三类统计信息。级联导入列级、索引级的统计信息参考IMPORT_INDEX_STATS和IMPORT_COLUMN_STATS接口的统计信息。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_import_table CASCADE; NOTICE: schema "dbe_stats_import_table" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集统计信息 gaussdb=# CREATE SCHEMA dbe_stats_import_table; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_import_table; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES (1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (3,3); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 创建用户统计信息表,导出表统计信息 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_import_table', 'export_table'); create_stat_table ------------------- (1 row) gaussdb=# CALL DBE_STATS.EXPORT_TABLE_STATS( gaussdb(# ownname => 'dbe_stats_import_table', gaussdb(# tabname => 't1', gaussdb(# partname => null, gaussdb(# stattab => 'export_table', gaussdb(# statid => 't1_t', gaussdb(# cascade => true gaussdb(# ); export_table_stats -------------------- (1 row) gaussdb=# -- 验证: 导出前 reltuples=3 gaussdb=# SELECT relname, reltuples FROM PG_CLASS WHERE oid='t1'::regclass; relname | reltuples ---------+----------- t1 | 3 (1 row) gaussdb=# INSERT INTO t1 VALUES (4,4); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (5,5); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (6,6); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# SELECT relname, reltuples FROM PG_CLASS WHERE oid='t1'::regclass; relname | reltuples ---------+----------- t1 | 6 (1 row) gaussdb=# CALL DBE_STATS.IMPORT_TABLE_STATS( gaussdb(# ownname => 'dbe_stats_import_table', gaussdb(# tabname => 't1', gaussdb(# partname => null, gaussdb(# stattab => 'export_table', gaussdb(# statid => 't1_t', gaussdb(# cascade => true, gaussdb(# force => false gaussdb(# ); import_table_stats -------------------- (1 row) gaussdb=# -- 验证: 导入后 reltuples恢复为3 gaussdb=# SELECT relname, reltuples FROM PG_CLASS WHERE oid='t1'::regclass; relname | reltuples ---------+----------- t1 | 3 (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_import_table; DROP SCHEMA
- DBE_STATS.IMPORT_COLUMN_STATS
从stattab标识的用户统计信息表中检索指定列(多列/表达式)的统计信息,并将其写回系统表中。该接口无返回值。
DBE_STATS.IMPORT_COLUMN_STATS原型为:
DBE_STATS.IMPORT_COLUMN_STATS ( ownname VARCHAR2, tabname VARCHAR2, colname VARCHAR2, partname VARCHAR2 DEFAULT NULL, stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, statown VARCHAR2 DEFAULT NULL, no_invalidate BOOLEAN DEFAULT NULL, force BOOLEAN DEFAULT FALSE );
表24 DBE_STATS.IMPORT_COLUMN_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
指定Schema的名称,如果设置为null,会默认使用当前的Schema。
tabname
VARCHAR2
否
指定需要导入统计信息的列所属的表名(表达式对应索引名)。
colname
VARCHAR2
否
列名或者多列名(tabname为索引时,colname为表达式名)。
partname
VARCHAR2
是
分区的名称。如果表/索引已分区但是partname为null,则导入全局和分区列/多列/索引表达式统计信息。
stattab
VARCHAR2
否
指定存储统计信息用户表的表名。
statid
VARCHAR2
是
指向stattab中统计信息的标识符(可选)。
statown
VARCHAR2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用ownname参数的值。
no_invalidate
BOOLEAN
是
暂不支持。
force
BOOLEAN
是
是否强制导入,忽略锁的状态,默认false。
- 导入列级的统计信息可查询PG_STATISTIC和PG_STATISTIC_EXT。
- 导入多列时,需先查询PG_STATISTIC_EXT中的staextname字段,获取多列别名作为colname参数传入。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_import_column CASCADE; NOTICE: schema "dbe_stats_import_column" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集统计信息 gaussdb=# CREATE SCHEMA dbe_stats_import_column; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_import_column; SET gaussdb=# CREATE TABLE IF NOT EXISTS t1 (a int, b int, c int) distribute by replication; CREATE TABLE gaussdb=# CREATE INDEX idx_t1_expr on t1((a*a), (a+a), (a*b)); CREATE INDEX gaussdb=# INSERT INTO t1 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (150, 550, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# ANALYZE t1((a,b)); ANALYZE gaussdb=# -- 建立用户统计信息表,导出列统计信息 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_import_column', 'export_table'); create_stat_table ------------------- (1 row) gaussdb=# CALL DBE_STATS.EXPORT_COLUMN_STATS( gaussdb(# ownname => 'dbe_stats_import_column', gaussdb(# tabname => 't1', gaussdb(# colname => 'a', gaussdb(# partname => null, gaussdb(# stattab => 'export_table', gaussdb(# statid => 't1_c' gaussdb(# ); export_column_stats --------------------- (1 row) gaussdb=# -- 查看导出结果 gaussdb=# SELECT relname, columnname, stadistinct, stakind1, stanumbers1, stavalues1 gaussdb-# FROM export_table order by 1,2,3,4; relname | columnname | stadistinct | stakind1 | stanumbers1 | stavalues1 ---------+------------+-------------+----------+-------------+------------ t1 | a | -.5 | 1 | {.666667} | {250} t1 | a | -.5 | 1 | {.666667} | {250} t1 | a | -.5 | 1 | {.666667} | {250} (3 rows) gaussdb=# -- 再次插入数据,收集统计信息 gaussdb=# INSERT INTO t1 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (150, 550, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 查看import前列统计信息 (stadistinct变化) gaussdb=# SELECT staattnum, stadistinct, stakind1, stanumbers1, stavalues1 gaussdb-# FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS ORDER BY 1; staattnum | stadistinct | stakind1 | stanumbers1 | stavalues1 -----------+-------------+----------+---------------------------+--------------- 1 | -.333333 | 1 | {.555556,.222222,.222222} | {250,100,150} 2 | -.333333 | 1 | {.555556,.222222,.222222} | {150,300,550} 3 | -.111111 | 1 | {1} | {1} (3 rows) gaussdb=# CALL DBE_STATS.IMPORT_COLUMN_STATS( gaussdb(# ownname => 'dbe_stats_import_column', gaussdb(# tabname => 't1', gaussdb(# colname => 'a', gaussdb(# partname => null, gaussdb(# stattab => 'export_table', gaussdb(# statid => 't1_c', gaussdb(# force => false gaussdb(# ); import_column_stats --------------------- (1 row) gaussdb=# -- 验证: 导入后列a的统计信息恢复 gaussdb=# SELECT staattnum, stadistinct, stakind1, stanumbers1, stavalues1 gaussdb-# FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS ORDER BY 1; staattnum | stadistinct | stakind1 | stanumbers1 | stavalues1 -----------+-------------+----------+---------------------------+--------------- 1 | -.5 | 1 | {.666667} | {250} 2 | -.333333 | 1 | {.555556,.222222,.222222} | {150,300,550} 3 | -.111111 | 1 | {1} | {1} (3 rows) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_import_column; DROP SCHEMA
- DBE_STATS.IMPORT_SCHEMA_STATS
从stattab标识的用户统计信息表中检索指定Schema的统计信息,并将其写回系统表中。该接口无返回值。
DBE_STATS.IMPORT_SCHEMA_STATS原型为:
DBE_STATS.IMPORT_SCHEMA_STATS ( ownname VARCHAR2, stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, statown VARCHAR2 DEFAULT NULL, no_invalidate BOOLEAN DEFAULT NULL, force BOOLEAN DEFAULT FALSE, stat_category VARCHAR2 DEFAULT NULL );
表25 DBE_STATS.IMPORT_SCHEMA_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
指定Schema的名称,如果设置为null,会默认使用当前的Schema。
stattab
VARCHAR2
否
指定存储统计信息用户表的表名。
statid
VARCHAR2
是
指向stattab中统计信息的标识符(可选)。
statown
VARCHAR2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用ownname参数的值。
no_invalidate
BOOLEAN
是
暂不支持。
force
BOOLEAN
是
是否强制导入,忽略锁的状态,默认false。
stat_category
VARCHAR2
是
暂不支持。
- 导入当前用户在指定Schema下所有具有权限的表的统计信息,对于无权限的表直接跳过,不报错。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_import_schema CASCADE; NOTICE: schema "dbe_stats_import_schema" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集统计信息 gaussdb=# CREATE SCHEMA dbe_stats_import_schema; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_import_schema; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES (1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (3,3); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 创建用户统计信息表,导出schema统计信息 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_import_schema', 'export_table'); create_stat_table ------------------- (1 row) gaussdb=# CALL DBE_STATS.EXPORT_SCHEMA_STATS( gaussdb(# ownname => 'dbe_stats_import_schema', gaussdb(# stattab => 'export_table', gaussdb(# statid => 's1' gaussdb(# ); export_schema_stats --------------------- (1 row) gaussdb=# -- 验证: 导出前 reltuples=3 gaussdb=# SELECT relname, reltuples FROM PG_CLASS WHERE oid='t1'::regclass; relname | reltuples ---------+----------- t1 | 3 (1 row) gaussdb=# -- 再次插入数据,收集统计信息 gaussdb=# INSERT INTO t1 VALUES (4,4); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (5,5); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (6,6); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 验证: 统计信息已更新 reltuples=6 gaussdb=# SELECT relname, reltuples FROM PG_CLASS WHERE oid='t1'::regclass; relname | reltuples ---------+----------- t1 | 6 (1 row) gaussdb=# -- 导入schema统计信息 gaussdb=# CALL DBE_STATS.IMPORT_SCHEMA_STATS( gaussdb(# ownname => 'dbe_stats_import_schema', gaussdb(# stattab => 'export_table', gaussdb(# statid => 's1', gaussdb(# force => false gaussdb(# ); import_schema_stats --------------------- (1 row) gaussdb=# -- 验证: 导入后 reltuples恢复为3 gaussdb=# SELECT relname, reltuples FROM PG_CLASS WHERE oid='t1'::regclass; relname | reltuples ---------+----------- t1 | 3 (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_import_schema; DROP SCHEMA
- DBE_STATS.IMPORT_DATABASE_STATS
从stattab标识的用户统计信息表中检索当前database用户表的统计信息,并将其写回系统表中。该接口无返回值。
DBE_STATS.IMPORT_DATABASE_STATS原型为:
DBE_STATS.IMPORT_DATABASE_STATS ( stattab VARCHAR2, statid VARCHAR2 DEFAULT NULL, statown VARCHAR2 DEFAULT NULL, no_invalidate BOOLEAN DEFAULT NULL, force BOOLEAN DEFAULT FALSE, stat_category VARCHAR2 DEFAULT NULL );表26 DBE_STATS.IMPORT_DATABASE_STATS接口参数说明 参数
类型
是否允许为空
描述
stattab
VARCHAR2
否
指定存储统计信息用户表的表名。
statid
VARCHAR2
是
指向stattab中统计信息的标识符(可选)。
statown
VARCHAR2
是
指定存储统计信息用户表所在Schema的名称,如果设置为null,会使用当前Schema。
no_invalidate
BOOLEAN
是
暂不支持。
force
BOOLEAN
是
是否强制导入,忽略锁的状态,默认false。
stat_category
VARCHAR2
是
暂不支持。
- 导入当前用户在指定database下所有具有analyze权限的用户表的统计信息,对于无权限的表直接跳过,不报错。
- 当statown参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_import_database CASCADE; NOTICE: schema "dbe_stats_import_database" does not exist, skipping DROP SCHEMA gaussdb=# -- 建表,收集统计信息 gaussdb=# CREATE SCHEMA dbe_stats_import_database; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_import_database; SET gaussdb=# CREATE TABLE t1(a int, b int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES (1,1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (2,2); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (3,3); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 创建用户统计信息表,导出database统计信息 gaussdb=# CALL DBE_STATS.CREATE_STAT_TABLE('dbe_stats_import_database', 'export_table'); create_stat_table ------------------- (1 row) gaussdb=# CALL DBE_STATS.EXPORT_DATABASE_STATS( gaussdb(# statown => 'dbe_stats_import_database', gaussdb(# stattab => 'export_table', gaussdb(# statid => 's1' gaussdb(# ); export_database_stats ----------------------- (1 row) gaussdb=# -- 验证: 导出前 reltuples=3 gaussdb=# SELECT relname, reltuples FROM PG_CLASS WHERE oid='t1'::regclass; relname | reltuples ---------+----------- t1 | 3 (1 row) gaussdb=# -- 再次插入数据,收集统计信息 gaussdb=# INSERT INTO t1 VALUES (4,4); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (5,5); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (6,6); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 验证: 统计信息已更新 reltuples=6 gaussdb=# SELECT relname, reltuples FROM PG_CLASS WHERE oid='t1'::regclass; relname | reltuples ---------+----------- t1 | 6 (1 row) gaussdb=# -- 导入database统计信息 gaussdb=# CALL DBE_STATS.IMPORT_DATABASE_STATS( gaussdb(# statown => 'dbe_stats_import_database', gaussdb(# stattab => 'export_table', gaussdb(# statid => 's1', gaussdb(# force => false gaussdb(# ); import_database_stats ----------------------- (1 row) gaussdb=# -- 验证: 导入后 reltuples恢复为3 gaussdb=# SELECT relname, reltuples FROM PG_CLASS WHERE oid='t1'::regclass; relname | reltuples ---------+----------- t1 | 3 (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP TABLE export_table; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_import_database; DROP SCHEMA - DBE_STATS.SET_COLUMN_STATS
设置列相关的统计信息,包括设置单列、多列和表达式统计信息。该接口无返回值。
DBE_STATS.SET_COLUMN_STATS原型为:
DBE_STATS.SET_COLUMN_STATS ( ownname VARCHAR2, tabname VARCHAR2, colname VARCHAR2, partname VARCHAR2 DEFAULT NULL, stattab VARCHAR2 DEFAULT NULL, statid VARCHAR2 DEFAULT NULL, distcnt NUMBER DEFAULT NULL, density NUMBER DEFAULT NULL, nullcnt NUMBER DEFAULT NULL, srec VARCHAR2 DEFAULT NULL, avgclen NUMBER DEFAULT NULL, flags NUMBER DEFAULT NULL, statown VARCHAR2 DEFAULT NULL, no_invalidate BOOLEAN DEFAULT NULL, force BOOLEAN DEFAULT FALSE, node_name VARCHAR2 DEFAULT NULL, option VARCHAR2 DEFAULT NULL );表27 DBE_STATS.SET_COLUMN_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
该表所在的Schema。如果设置为null,则默认使用当前Schema。
tabname
VARCHAR2
否
表名。
colname
VARCHAR2
否
列名。
partname
VARCHAR2
是
要设置统计信息的表分区的名称。如果表已分区且partname为null,则设置全局级别的列级统计信息。
stattab
VARCHAR2
是
暂不支持此参数。
statid
VARCHAR2
是
暂不支持此参数。
distcnt
NUMBER
是
设置该列中NDV数量。
density
NUMBER
是
暂不支持。
nullcnt
NUMBER
是
设置该列中null值数量。
srec
VARCHAR2
是
暂不支持此参数。
avgclen
NUMBER
是
设置该列中字段的平均长度(以字节为单位)。
flags
NUMBER
是
暂不支持此参数。
statown
VARCHAR2
是
暂不支持此参数。
no_invalidate
BOOLEAN
是
暂不支持此参数。
force
BOOLEAN
是
决定统计信息被锁定时的行为。如果为true,则即使列级统计信息被锁定,该过程也会设置值。默认为false。
node_name
VARCHAR2
是
node_name为null会更新所有CN和DN节点的统计信息;
node_name为DN节点名仅会更新指定DN的统计信息;
node_name为CN节点名会更新所有CN的统计信息
option
VARCHAR2
是
DN节点NDV的计算方式,仅在node_name为null时生效,当前只允许"p", "s"。
"p":表示使用泊松分布计算DN节点的NDV值。
"s":表示DN节点和CN节点使用同一NDV值。
- 该接口支持设置表达式统计信息,由于表达式的创建依赖于索引,因此当调用该接口设置表达式统计信息时,tabname应该传入该索引的名称。
- 当前仅支持设置列的NDV(distcnt)、nullfrac(nullcnt)和width(avgclen)三类统计信息。
- 当单列、表达式统计信息被删除后,仍然支持调用该接口设置对应的单列、表达式统计信息,此时PG_STATISTIC系统表中将插入新的数据。但对于多列统计信息,当其被删除后,不支持使用该接口进行重新设置。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
- 当前列的行数(reltuples)为0时,nullfrac将会被设置为0,distcnt将会被设置为入参的值。
示例:
-- 前置条件,建表,收集统计信息。 gaussdb=# CREATE SCHEMA dbe_stats_set_schema; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_set_schema; SET gaussdb=# DROP TABLE IF EXISTS t1; NOTICE: table "t1" does not exist, skipping DROP TABLE gaussdb=# CREATE TABLE IF NOT EXISTS t1 (a int, b int, c int) distribute by replication; CREATE TABLE gaussdb=# CREATE INDEX idx_t1_expr ON t1((a*a), (a+a), (a*b)); CREATE INDEX gaussdb=# INSERT INTO t1 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (150, 550, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# ANALYZE t1((a, b)); ANALYZE -- 设置单列统计信息。 -- 查询原有统计信息。 gaussdb=# SELECT staattnum,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS ORDER BY 1; staattnum | stanullfrac | stawidth | stadistinct -----------+-------------+----------+------------- 1 | 0 | 4 | -.75 2 | 0 | 4 | -.75 3 | 0 | 4 | -.25 (3 rows) -- 设置列级统计信息后重新查询。 gaussdb=# CALL DBE_STATS.SET_COLUMN_STATS(ownname => 'dbe_stats_set_schema', tabname => 't1', colname => 'a', distcnt => 6, nullcnt => 5, avgclen => 42); set_column_stats ------------------ (1 row) gaussdb=# SELECT staattnum,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS ORDER BY 1; staattnum | stanullfrac | stawidth | stadistinct -----------+-------------+----------+------------- 1 | 1 | 42 | 6 2 | 0 | 4 | -.75 3 | 0 | 4 | -.25 (3 rows) -- 设置多列统计信息。 -- 查询原有统计信息。 gaussdb=# SELECT stakey,staextname,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC_EXT WHERE starelid='t1'::REGCLASS; stakey | staextname | stanullfrac | stawidth | stadistinct --------+---------------------+-------------+----------+------------- 1 2 | extname_-1308656218 | 0 | 8 | -.75 (1 row) -- 设置统计信息后重新查询。 gaussdb=# CALL DBE_STATS.SET_COLUMN_STATS(ownname => 'dbe_stats_set_schema', tabname => 't1', colname => 'extname_-1308656218', distcnt => 5, nullcnt => 5, avgclen => 2); set_column_stats ------------------ (1 row) gaussdb=# SELECT stakey,staextname,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC_EXT WHERE starelid='t1'::REGCLASS; stakey | staextname | stanullfrac | stawidth | stadistinct --------+---------------------+-------------+----------+------------- 1 2 | extname_-1308656218 | 1 | 2 | 5 (1 row) -- 设置表达式统计信息。 -- 查询原有统计信息。 gaussdb=# SELECT staattnum,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC WHERE starelid='idx_t1_expr'::REGCLASS ORDER BY 1; staattnum | stanullfrac | stawidth | stadistinct -----------+-------------+----------+------------- 1 | 0 | 4 | -.75 2 | 0 | 4 | -.75 3 | 0 | 4 | -.75 (3 rows) -- 查询表达式列名。 gaussdb=# SELECT attnum, attname FROM PG_ATTRIBUTE WHERE attrelid='idx_t1_expr'::REGCLASS ORDER BY 1; attnum | attname --------+--------- 1 | expr 2 | expr1 3 | expr2 (3 rows) -- 设置统计信息后重新查询。 gaussdb=# CALL DBE_STATS.SET_COLUMN_STATS(ownname => 'dbe_stats_set_schema', tabname => 'idx_t1_expr', colname => 'expr', distcnt => 13, nullcnt => 5, avgclen => 22); set_column_stats ------------------ (1 row) gaussdb=# SELECT staattnum,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC WHERE starelid='idx_t1_expr'::REGCLASS ORDER BY 1; staattnum | stanullfrac | stawidth | stadistinct -----------+-------------+----------+------------- 1 | 1 | 22 | 13 2 | 0 | 4 | -.75 3 | 0 | 4 | -.75 (3 rows) -- 设置指定DN的统计信息。 gaussdb=# CALL DBE_STATS.SET_COLUMN_STATS(ownname => 'dbe_stats_set_schema', tabname => 't1', colname => 'a', distcnt => 3, nullcnt => 3,avgclen => 3, node_name=>'dn_6007_6008_6009'); set_column_stats ------------------ (1 row) gaussdb=# EXECUTE DIRECT ON (dn_6007_6008_6009) $$SELECT staattnum,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS AND staattnum = 1;$$; staattnum | stanullfrac | stawidth | stadistinct -----------+-------------+----------+------------- 1 | .75 | 3 | 3 (1 row) -- 设置所有CN的统计信息。 gaussdb=# CALL DBE_STATS.SET_COLUMN_STATS(ownname => 'dbe_stats_set_schema', tabname => 't1', colname => 'a', distcnt => 6, nullcnt => 6,avgclen => 6, node_name=>'cn_5002'); set_column_stats ------------------ (1 row) gaussdb=# EXECUTE DIRECT ON (cn_5002) $$SELECT staattnum,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS AND staattnum = 1;$$; staattnum | stanullfrac | stawidth | stadistinct -----------+-------------+----------+------------- 1 | 1 | 6 | 6 (1 row) -- 设置整个集群的统计信息,其中DN的distcnt值和CN保持一致。 gaussdb=# CALL DBE_STATS.SET_COLUMN_STATS(ownname => 'dbe_stats_set_schema', tabname => 't1', colname => 'a', distcnt => 100, nullcnt => 100,avgclen => 100, option=>'s'); set_column_stats ------------------ (1 row) gaussdb=# EXECUTE DIRECT ON (cn_5002) $$SELECT staattnum,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS AND staattnum = 1;$$; staattnum | stanullfrac | stawidth | stadistinct -----------+-------------+----------+------------- 1 | 1 | 100 | 100 (1 row) gaussdb=# EXECUTE DIRECT ON (dn_6007_6008_6009) $$SELECT staattnum,stanullfrac,stawidth,stadistinct FROM PG_STATISTIC WHERE starelid='t1'::REGCLASS AND staattnum = 1;$$; staattnum | stanullfrac | stawidth | stadistinct -----------+-------------+----------+------------- 1 | 1 | 100 | 100 (1 row) -- 设置指定DN的行数和页数。 gaussdb=# CALL DBE_STATS.SET_TABLE_STATS(tabname => 't1', ownname => 'dbe_stats_set_schema', numrows => 3, numblks => 3, relallvisible => 1, node_name=>'dn_6007_6008_6009'); set_table_stats ----------------- (1 row) -- 设置整个集群的统计信息,其中DN的distcnt值采用泊松分布计算。 gaussdb=# CALL DBE_STATS.SET_COLUMN_STATS(ownname => 'dbe_stats_set_schema', tabname => 't1', colname => 'a', distcnt => 100, nullcnt => 100,avgclen => 100, option=>'p'); set_column_stats ------------------ (1 row) -- 删除表、命名空间。 gaussdb=# DROP INDEX idx_t1_expr; DROP INDEX gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_set_schema cascade; DROP SCHEMA
- DBE_STATS.SET_INDEX_STATS
DBE_STATS.SET_INDEX_STATS原型为:
DBE_STATS.SET_INDEX_STATS ( ownname VARCHAR2, indname VARCHAR2, partname VARCHAR2 DEFAULT NULL, stattab VARCHAR2 DEFAULT NULL, statid VARCHAR2 DEFAULT NULL, numrows NUMBER DEFAULT NULL, numlblks NUMBER DEFAULT NULL, relallvisible NUMBER DEFAULT NULL, numdist NUMBER DEFAULT NULL, avglblk NUMBER DEFAULT NULL, avgdblk NUMBER DEFAULT NULL, clstfct NUMBER DEFAULT NULL, indlevel NUMBER DEFAULT NULL, flags NUMBER DEFAULT NULL, statown VARCHAR2 DEFAULT NULL, no_invalidate BOOLEAN DEFAULT NULL, guessq NUMBER DEFAULT NULL, cachedblk NUMBER DEFAULT NULL, cachehit NUMBER DEFAULT NULL, force BOOLEAN DEFAULT FALSE, node_name VARCHAR2 DEFAULT NULL );表28 DBE_STATS.SET_INDEX_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
该索引所在的Schema。如果设置为null,则默认使用当前Schema。
indname
VARCHAR2
否
索引名。
partname
VARCHAR2
是
要设置统计信息的索引分区的名称。如果索引已分区且partname为null,则设置全局索引级别的统计信息。
stattab
VARCHAR2
是
暂不支持该参数。
statid
VARCHAR2
是
暂不支持该参数。
numrows
NUMBER
是
设置索引的行数。
numlblks
NUMBER
是
设置索引的页数。
relallvisible
NUMBER
是
设置被标识为全可见的索引中的页的数量。
numdist
NUMBER
是
暂不支持该参数。
avglblk
NUMBER
是
暂不支持此参数。
avgdblk
NUMBER
是
暂不支持此参数。
clstfct
NUMBER
是
暂不支持此参数。
indlevel
NUMBER
是
暂不支持此参数。
flags
NUMBER
是
暂不支持此参数。
statown
VARCHAR2
是
暂不支持此参数。
no_invalidate
BOOLEAN
是
暂不支持此参数。
guessq
NUMBER
是
暂不支持此参数。
cachedblk
NUMBER
是
暂不支持此参数。
cachehit
NUMBER
是
暂不支持此参数。
force
BOOLEAN
是
决定统计信息被锁定时的行为。如果为TRUE,则即使索引统计信息被锁定,该过程也会设置值。默认为false。
node_name
VARCHAR2
是
node_name为null会更新所有CN和DN节点的统计信息;
node_name为DN节点名仅会更新指定DN的统计信息;
node_name为CN节点名会更新所有CN的统计信息。
- 当前仅支持设置索引的reltuples(numrows)、relpages(numlblks)和relallvisible(relallvisible)三类统计信息。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
-- 前置条件,建表,收集统计信息。 gaussdb=# CREATE SCHEMA dbe_stats_set_schema; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_set_schema; SET gaussdb=# DROP TABLE IF EXISTS t1; NOTICE: table "t1" does not exist, skipping DROP TABLE gaussdb=# CREATE TABLE IF NOT EXISTS t1 (a int, b int, c int) distribute by replication; CREATE TABLE gaussdb=# CREATE INDEX idx_t1_a on t1(a); CREATE INDEX gaussdb=# INSERT INTO t1 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (150, 550, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE -- 设置索引统计信息。 -- 查看当前索引统计信息。 gaussdb=# SELECT reltuples FROM PG_CLASS WHERE relname='idx_t1_a'; reltuples ----------- 3 (1 row) -- 设置统计信息后重新查询。 gaussdb=# CALL DBE_STATS.SET_INDEX_STATS(indname => 'idx_t1_a', ownname => 'dbe_stats_set_schema', numrows => 1, numlblks => 3, relallvisible => 6); set_index_stats ----------------- (1 row) gaussdb=# SELECT reltuples,relpages,relallvisible FROM PG_CLASS WHERE relname='idx_t1_a'; reltuples | relpages | relallvisible -----------+----------+--------------- 1 | 3 | 6 (1 row) -- 设置指定DN的统计信息。 gaussdb=# CALL DBE_STATS.SET_INDEX_STATS(indname => 'idx_t1_a', ownname => 'dbe_stats_set_schema', numrows => 2, numlblks => 2, relallvisible => 2,node_name=>'dn_6007_6008_6009'); set_index_stats ----------------- (1 row) -- 查询指定DN的统计信息。 gaussdb=# EXECUTE DIRECT ON (dn_6007_6008_6009) $$SELECT reltuples,relpages,relallvisible FROM PG_CLASS WHERE relname='idx_t1_a'$$; reltuples | relpages | relallvisible -----------+----------+--------------- 2 | 2 | 2 (1 row) -- 设置指定CN的统计信息。 gaussdb=# CALL DBE_STATS.SET_INDEX_STATS(indname => 'idx_t1_a', ownname => 'dbe_stats_set_schema', numrows => 10, numlblks => 100, relallvisible => 10,node_name=>'cn_5001'); set_index_stats ----------------- (1 row) -- 查询指定CN的统计信息。 gaussdb=# EXECUTE DIRECT ON (cn_5001) $$SELECT reltuples,relpages,relallvisible FROM PG_CLASS WHERE relname='idx_t1_a'$$; reltuples | relpages | relallvisible -----------+----------+--------------- 10 | 100 | 10 (1 row) -- 删除表、命名空间。 gaussdb=# DROP INDEX idx_t1_a; DROP INDEX gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_set_schema CASCADE; DROP SCHEMA
- DBE_STATS.SET_TABLE_STATS
DBE_STATS.SET_TABLE_STATS原型为:
DBE_STATS.SET_TABLE_STATS ( ownname VARCHAR2, tabname VARCHAR2, partname VARCHAR2 DEFAULT NULL, stattab VARCHAR2 DEFAULT NULL, statid VARCHAR2 DEFAULT NULL, numrows NUMBER DEFAULT NULL, numblks NUMBER DEFAULT NULL, relallvisible NUMBER DEFAULT NULL, avgrlen NUMBER DEFAULT NULL, flags NUMBER DEFAULT NULL, statown VARCHAR2 DEFAULT NULL, no_invalidate BOOLEAN DEFAULT NULL, cachedblk NUMBER DEFAULT NULL, cachehit NUMBER DEFAULT NULL, force BOOLEAN DEFAULT FALSE, im_imcu_count NUMBER DEFAULT NULL, im_block_count NUMBER DEFAULT NULL, scanrate NUMBER DEFAULT NULL, node_name VARCHAR2 DEFAULT NULL );表29 DBE_STATS.SET_TABLE_STATS接口参数说明 参数
类型
是否允许为空
描述
ownname
VARCHAR2
否
该表所在的Schema。如果设置为null,则默认使用当前Schema。
tabname
VARCHAR2
否
表名。
partname
VARCHAR2
是
要设置统计信息的表分区的名称。如果表已分区且partname为null,则设置全局表级别的统计信息。
stattab
VARCHAR2
是
暂不支持该参数。
statid
VARCHAR2
是
暂不支持该参数。
numrows
NUMBER
是
设置表的行数。
numblks
NUMBER
是
设置表的页数。
relallvisible
NUMBER
是
设置被标识为全可见的表中的页的数量。
avgrlen
NUMBER
是
暂不支持该参数。
flags
NUMBER
是
暂不支持此参数。
statown
VARCHAR2
是
暂不支持此参数。
no_invalidate
BOOLEAN
是
暂不支持此参数。
cachedblk
NUMBER
是
暂不支持此参数。
cachehit
NUMBER
是
暂不支持此参数。
force
BOOLEAN
是
决定统计信息被锁定时的行为。如果为TRUE,则即使表统计信息被锁定,该过程也会设置值。默认为false。
im_imcu_count
NUMBER
是
暂不支持此参数。
im_block_count
NUMBER
是
暂不支持此参数。
scanrate
NUMBER
是
暂不支持此参数。
node_name
VARCHAR2
是
node_name为null会更新所有CN和DN节点的统计信息;
node_name为DN节点名仅会更新指定DN的统计信息;
node_name为CN节点名会更新所有CN的统计信息。
- 当前仅支持设置表的reltuples(numrows)、relpages(numblks)和relallvisible(relallvisible)三类统计信息。
- 当ownname参数值设置为null时使用当前Schema,需将behavior_compat_options参数值设置为bind_procedure_searchpath。
示例:
gaussdb=# DROP SCHEMA IF EXISTS dbe_stats_set_schema_table CASCADE; NOTICE: schema "dbe_stats_set_schema_table" does not exist, skipping DROP SCHEMA gaussdb=# -- 前置条件,建表,收集统计信息 gaussdb=# CREATE SCHEMA dbe_stats_set_schema_table; CREATE SCHEMA gaussdb=# SET CURRENT_SCHEMA = dbe_stats_set_schema_table; SET gaussdb=# DROP TABLE IF EXISTS t1; NOTICE: table "t1" does not exist, skipping DROP TABLE gaussdb=# CREATE TABLE IF NOT EXISTS t1 (a int, b int, c int) distribute by replication; CREATE TABLE gaussdb=# INSERT INTO t1 VALUES (100, 300, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (150, 550, 1); INSERT 0 1 gaussdb=# INSERT INTO t1 VALUES (250, 150, 1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# -- 查看当前表统计信息 gaussdb=# SELECT reltuples, relpages, relallvisible FROM PG_CLASS WHERE oid='t1'::regclass; reltuples | relpages | relallvisible -----------+----------+--------------- 3 | 1 | 0 (1 row) gaussdb=# -- 设置表级统计信息 (numrows=3, numblks=3, relallvisible=3) gaussdb=# CALL DBE_STATS.SET_TABLE_STATS( gaussdb(# tabname => 't1', gaussdb(# ownname => 'dbe_stats_set_schema_table', gaussdb(# numrows => 3, gaussdb(# numblks => 3, gaussdb(# relallvisible => 3 gaussdb(# ); set_table_stats ----------------- (1 row) gaussdb=# -- 验证: 表统计信息已设置 (reltuples=3, relpages=3, relallvisible=3) gaussdb=# SELECT reltuples, relpages, relallvisible FROM PG_CLASS WHERE oid='t1'::regclass; reltuples | relpages | relallvisible -----------+----------+--------------- 3 | 3 | 3 (1 row) gaussdb=# -- 清理 gaussdb=# DROP TABLE t1; DROP TABLE gaussdb=# DROP SCHEMA dbe_stats_set_schema_table CASCADE; DROP SCHEMA
- DBE_STATS.GET_TABLES_BY_SQLID
获取Unique SQL ID对应语句所有涉及的表,如果包含多张表,则返回多行记录。
DBE_STATS.GET_TABLES_BY_SQLID原型为:DBE_STATS.GET_TABLES_BY_SQLID ( unique_sqlid BIGINT ) RETURNS TABLE ( nspname TEXT, tabname TEXT );表30 DBE_STATS.GET_TABLES_BY_SQLID接口参数与返回值说明 字段名
数据类型
字段类型
是否允许为空
描述
unique_sqlid
BIGINT
IN
否
唯一SQL ID,可通过pg_catalog.pg_stat_activity(实时会话信息视图)、dbe_perf.statement(归一化SQL语句记录视图)或dbe_perf.statement_history(全量或慢SQL语句记录视图)中查询获得。
nspname
TEXT
OUT
否
语句中涉及表的模式名称。
tabname
TEXT
OUT
否
语句中涉及表的名称。
示例:
-- 前置条件 gaussdb=# DROP TABLE IF EXISTS t1; DROP TABLE gaussdb=# CREATE TABLE t1 (c1 int) DISTRIBUTE BY HASH (c1); CREATE TABLE gaussdb=# INSERT INTO t1 VALUES (1); INSERT 0 1 gaussdb=# CREATE OR REPLACE PROCEDURE select_t1() gaussdb-# AS gaussdb$# BEGIN gaussdb$# PERFORM * FROM t1; gaussdb$# END; gaussdb$# / CREATE PROCEDURE gaussdb=# DROP TABLE IF EXISTS t2; DROP TABLE gaussdb=# CREATE TABLE t2 (c1 int) DISTRIBUTE BY HASH (c1) PARTITION BY LIST (c1) ( gaussdb(# PARTITION t2_p1 VALUES (1), gaussdb(# PARTITION t2_p2 VALUES (2) gaussdb(# ); CREATE TABLE gaussdb=# INSERT INTO t2 VALUES (1), (2); INSERT 0 2 -- 使用从pgxc_stat_activity中查询的unique sqlid。 -- 会话1:模拟无法执行的语句。 gaussdb=# SET cursor_sharing = off; -- 避免自动参数化不执行解析。 SET gaussdb=# SELECT pg_sleep(60) from t1; pg_sleep ---------- (1 row) -- 会话2:在会话一执行期间查询其unique sqlid,并查询对应的tabname,语句需根据实际sql_id调整。 gaussdb=# SELECT query, sessionid, unique_sql_id FROM pgxc_stat_activity WHERE query LIKE '%pg_sleep%t1%' AND query NOT LIKE '%pgxc_stat_activity%'; query | sessionid | unique_sql_id ------------------------------+-----------+--------------- SELECT pg_sleep(60) FROM t1; | 1 | 3101300097 (1 row) gaussdb=# SELECT * FROM dbe_stats.get_tables_by_sqlid(3101300097); nspname | tabname ---------+--------- public | t1 (1 row) -- 2.使用从dbe_perf.statement中查询的unique sqlid。 gaussdb=# SHOW instr_unique_sql_count; -- 查看statement视图中的最大记录数。 instr_unique_sql_count ------------------------ 200000 (1 row) gaussdb=# SELECT count(*) FROM dbe_perf.summary_statement; -- 确认statement视图中的记录数是否超限。 count ------- 46 (1 row) gaussdb=# SELECT reset_unique_sql('GLOBAL','ALL',0); -- 如果达到限制,后续的语句不会再记录,可以清空记录(注:会导致SQL记录丢失)。 reset_unique_sql ------------------ t (1 row) gaussdb=# SELECT * FROM t1; c1 ---- 1 (1 row) gaussdb=# SELECT unique_sql_id FROM dbe_perf.summary_statement WHERE query LIKE '%SELECT * FROM t1%'; unique_sql_id --------------- 4115569441 (1 row) gaussdb=# SELECT * FROM dbe_stats.get_tables_by_sqlid(4115569441); nspname | tabname ---------+--------- public | t1 (1 row) -- 3.使用从dbe_stats.statement_history中查询的unique sqlid。 gaussdb=# SET log_min_duration_statement = '1s'; -- 执行时间>=1s的慢SQL会被记录。 SET gaussdb=# DELETE FROM pg_catalog.statement_history; -- 避免受残留的慢SQL记录影响。 DELETE 2 gaussdb=# SELECT pg_sleep(1) FROM t1; pg_sleep ---------- (1 row) gaussdb=# SELECT unique_query_id FROM dbe_perf.statement_history WHERE query LIKE '%pg_sleep%t1%' LIMIT 1; unique_query_id ----------------- 3101300097 (1 row) gaussdb=# SELECT * FROM dbe_stats.get_tables_by_sqlid(3101300097); nspname | tabname ---------+--------- public | t1 (1 row) -- 4.使用存储过程的unique sqlid,从dbe_stats.statement中查询。 gaussdb=# SHOW instr_unique_sql_track_type; -- 确认此时statement视图记录包括存储过程子语句。 instr_unique_sql_track_type ----------------------------- all (1 row) gaussdb=# SELECT * FROM select_t1(); select_t1 ----------- (1 row) gaussdb=# SELECT s1.query, s1.unique_sql_id FROM dbe_perf.summary_statement s1 WHERE s1.query = 'SELECT * FROM select_t1();' gaussdb-# UNION ALL gaussdb-# SELECT s2.query, s2.unique_sql_id FROM dbe_perf.summary_statement s1, dbe_perf.summary_statement s2 WHERE s1.query = 'SELECT * FROM select_t1();' AND s1.unique_sql_id = s2.parent_unique_sql_id; query | unique_sql_id ----------------------------+--------------- SELECT * FROM select_t1(); | 1861705880 SELECT * FROM t1 | 4115569441 (2 rows) gaussdb=# SELECT * FROM dbe_stats.get_tables_by_sqlid(1861705880); -- 顶层语句不包含基表。 nspname | tabname ---------+--------- (0 rows) gaussdb=# SELECT * FROM dbe_stats.get_tables_by_sqlid(4115569441); -- 子语句包含基表。 nspname | tabname ---------+--------- public | t1 (1 row) -- 5.在dbe_perf.statement中查询,涉及多张表的语句。 gaussdb=# SELECT * FROM t1, t2 LIMIT 1; c1 | c1 ----+---- 1 | 1 (1 row) gaussdb=# SELECT query, unique_sql_id FROM dbe_perf.summary_statement WHERE query LIKE '%SELECT * FROM t1, t2 LIMIT%'; query | unique_sql_id -------------------------------+--------------- SELECT * FROM t1, t2 LIMIT ?; | 2763456878 (1 row) gaussdb=# SELECT * FROM dbe_stats.get_tables_by_sqlid(2763456878); nspname | tabname ---------+--------- public | t1 public | t2 (2 rows) -- 后置操作 gaussdb=# DROP PROCEDURE IF EXISTS select_t1; DROP PROCEDURE gaussdb=# DROP TABLE IF EXISTS t1; DROP TABLE gaussdb=# DROP TABLE IF EXISTS t2; DROP TABLE - DBE_STATS.ANALYZE_SQLID
获取Unique SQL ID对应语句所有涉及的表,以及收集对应表的统计信息。对于收集成功的表,如果包含多张表,则返回多行记录。
DBE_STATS.ANALYZE_SQLID原型为:DBE_STATS.ANALYZE_SQLID ( unique_sqlid BIGINT, all_complete BOOLEAN DEFAULT FALSE, node_name NAME DEFAULT NULL ) RETURNS TABLE ( nspname TEXT, tabname TEXT );表31 DBE_STATS.ANALYZE_SQLID接口参数与返回值说明 字段名
数据类型
字段类型
是否允许为空
描述
unique_sqlid
BIGINT
IN
否
唯一SQL ID,可通过pg_catalog.pg_stat_activity(实时会话信息视图)、dbe_perf.statement(归一化SQL语句记录视图)或dbe_perf.statement_history(全量或慢SQL语句记录视图)中查询获得。
all_complete
BOOLEAN
IN
是
指定是否使用ALL COMPLETE模式进行统计信息收集,与ANALYZE tabname WITH ALL COMPLETE的行为一致。未指定则使用默认模式,对应ANALYZE tabname。
node_name
NAME
IN
是
CN节点名,对应pgxc_node.node_name。如果指定了CN名,则只查询对应CN中的SQL语句记录,未指定则查询所有CN中的记录。
nspname
TEXT
OUT
否
语句中涉及表的模式名称。
tabname
TEXT
OUT
否
语句中涉及表的名称。仅包含成功收集统计信息的表。
示例:
-- ANALYZE_SQLID的使用方法与上述GET_TABLES_SQLID基本相同,除了本接口会实际收集统计信息,以及提供了all_complete选项、node_name节点入参的筛选。 -- 前置条件。 gaussdb=# DROP TABLE IF EXISTS t1; DROP TABLE gaussdb=# CREATE TABLE t1 (c1 int) DISTRIBUTE BY HASH (c1); CREATE TABLE gaussdb=# INSERT INTO t1 VALUES (1); INSERT 0 1 gaussdb=# ANALYZE t1; ANALYZE gaussdb=# CREATE OR REPLACE PROCEDURE select_t1() gaussdb-# AS gaussdb$# BEGIN gaussdb$# PERFORM * FROM t1; gaussdb$# END; gaussdb$# / CREATE PROCEDURE gaussdb=# DROP TABLE IF EXISTS t2; DROP TABLE gaussdb=# CREATE TABLE t2 (c1 int) DISTRIBUTE BY HASH (c1) PARTITION BY LIST (c1) ( gaussdb(# PARTITION t2_p1 VALUES (1), gaussdb(# PARTITION t2_p2 VALUES (2) gaussdb(# ); CREATE TABLE gaussdb=# INSERT INTO t2 VALUES (1), (2); INSERT 0 2 gaussdb=# ANALYZE t2; ANALYZE -- 1.使用从pgxc_stat_activity中查询的unique sqlid。 -- 会话1:模拟无法执行的语句。 gaussdb=# SET cursor_sharing = off; -- 避免自动参数化不执行解析。 SET gaussdb=# SELECT pg_sleep(60) FROM t1; pg_sleep ---------- (1 row) -- 会话2:在会话一执行期间查询其unique sqlid,并查询对应的tabname,语句需根据实际sql_id调整。 gaussdb=# SELECT query, sessionid, unique_sql_id FROM pgxc_stat_activity WHERE query LIKE '%pg_sleep%t1%' AND query NOT LIKE '%pgxc_stat_activity%'; query | sessionid | unique_sql_id ------------------------------+-----------+--------------- SELECT pg_sleep(60) FROM t1; | 1 | 3101300097 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't1'; -- 此前的analyze次数。 analyze_count --------------- 1 (1 row) gaussdb=# SELECT * FROM dbe_stats.analyze_sqlid(3101300097); nspname | tabname ---------+--------- public | t1 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't1'; -- 确认以上操作完成了一次analyze。 analyze_count --------------- 2 (1 row) -- 2.使用从dbe_perf.statement中查询的unique sqlid。 gaussdb=# SHOW instr_unique_sql_count; -- 查看statement视图中的最大记录数。 instr_unique_sql_count ------------------------ 200000 (1 row) gaussdb=# SELECT count(*) FROM dbe_perf.summary_statement; -- 确认statement视图中的记录数是否超限。 count ------- 46 (1 row) gaussdb=# SELECT reset_unique_sql('GLOBAL','ALL',0); -- 如果达到限制,后续的语句不会再记录,可以清空记录(注:会导致SQL记录丢失)。 reset_unique_sql ------------------ t (1 row) gaussdb=# SELECT * FROM t1; c1 ---- 1 (1 row) gaussdb=# SELECT unique_sql_id FROM dbe_perf.summary_statement WHERE query LIKE '%SELECT * FROM t1%'; unique_sql_id --------------- 4115569441 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't1'; -- 此前的analyze次数。 analyze_count --------------- 2 (1 row) gaussdb=# SELECT * FROM dbe_stats.analyze_sqlid(4115569441); nspname | tabname ---------+--------- public | t1 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't1'; -- 确认以上操作完成了一次analyze。 analyze_count --------------- 3 (1 row) -- 3.使用从dbe_stats.statement_history中查询的unique sqlid。 gaussdb=# SET log_min_duration_statement = '1s'; -- 执行时间>=1s的慢SQL会被记录。 SET gaussdb=# DELETE FROM pg_catalog.statement_history; -- 避免受残留的慢SQL记录影响。 DELETE 2 gaussdb=# SELECT pg_sleep(1) FROM t1; pg_sleep ---------- (1 row) gaussdb=# SELECT unique_query_id FROM dbe_perf.statement_history WHERE query LIKE '%pg_sleep%t1%' LIMIT 1; unique_query_id ----------------- 3101300097 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't1'; -- 此前的analyze次数。 analyze_count --------------- 3 (1 row) gaussdb=# SELECT * FROM dbe_stats.analyze_sqlid(3101300097); nspname | tabname ---------+--------- public | t1 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't1'; -- 确认以上操作完成了一次analyze。 analyze_count --------------- 4 (1 row) -- 4.使用存储过程的unique sqlid,从dbe_stats.statement中查询。 gaussdb=# SHOW instr_unique_sql_track_type; -- 确认此时statement视图记录包括存储过程子语句。 instr_unique_sql_track_type ----------------------------- all (1 row) gaussdb=# SELECT * FROM select_t1(); select_t1 ----------- (1 row) gaussdb=# SELECT s1.query, s1.unique_sql_id FROM dbe_perf.summary_statement s1 WHERE s1.query = 'SELECT * FROM select_t1();' gaussdb-# UNION ALL gaussdb-# SELECT s2.query, s2.unique_sql_id FROM dbe_perf.summary_statement s1, dbe_perf.summary_statement s2 WHERE s1.query = 'SELECT * FROM select_t1();' AND s1.unique_sql_id = s2.parent_unique_sql_id; query | unique_sql_id ----------------------------+--------------- SELECT * FROM select_t1(); | 1861705880 SELECT * FROM t1 | 4115569441 (2 rows) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't1'; -- 此前的analyze次数。 analyze_count --------------- 4 (1 row) gaussdb=# SELECT * FROM dbe_stats.analyze_sqlid(1861705880); -- 顶层语句不包含基表。 nspname | tabname ---------+--------- (0 rows) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't1'; -- 以上操作并没有触发t1表的analyze。 analyze_count --------------- 4 (1 row) gaussdb=# SELECT * FROM dbe_stats.analyze_sqlid(4115569441); -- 子语句包含基表。 nspname | tabname ---------+--------- public | t1 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't1'; -- 确认以上操作完成了一次analyze。 analyze_count --------------- 5 (1 row) -- 5.查询dbe_perf.statement,并对分区表使用all_complete模式进行统计信息收集。 gaussdb=# SELECT * FROM t2; c1 ---- 1 2 (2 rows) gaussdb=# SELECT query, unique_sql_id FROM dbe_perf.summary_statement WHERE query LIKE '%SELECT * FROM t2%'; query | unique_sql_id -------------------+--------------- SELECT * FROM t2; | 909667705 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't2'; -- 此前的analyze次数。 analyze_count --------------- 1 (1 row) gaussdb=# SELECT * FROM dbe_stats.analyze_sqlid(909667705, true); -- 使用all_complete模式,每个分区会采集更大的样本。 nspname | tabname ---------+--------- public | t2 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't2'; -- 确认以上操作完成了一次analyze。 analyze_count --------------- 2 (1 row) -- 6.用node_name筛选,仅查询当前CN节点的SQL记录并收集相关统计信息,假设当前连接节点为data_coordinator1。 gaussdb=# SELECT node_name, node_type, node_port FROM pgxc_node; node_name | node_type | node_port -------------------+-----------+----------- data_coordinator1 | C | 36415 data_coordinator2 | C | 36419 data_coordinator3 | C | 36423 data_datanode1 | D | 36815 data_datanode2 | D | 36819 data_datanode3 | D | 36823 (6 rows) gaussdb=# select * from t2; c1 ---- 1 2 (2 rows) gaussdb=# SELECT unique_sql_id, node_name FROM dbe_perf.summary_statement WHERE query LIKE '%SELECT * FROM t2%'; -- 对应的语句记录在CN1节点上。 unique_sql_id | node_name ---------------+------------------- 57714958 | data_coordinator1 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't2'; -- 此前的analyze次数。 analyze_count --------------- 2 (1 row) gaussdb=# SELECT * FROM dbe_stats.analyze_sqlid(57714958, true, 'data_coordinator1'); nspname | tabname ---------+--------- public | t2 (1 row) gaussdb=# SELECT analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname = 't2'; -- 确认以上操作完成了一次analyze。 analyze_count --------------- 3 (1 row) -- 7.在dbe_perf.statement中查询并收集,涉及多张表的语句。 gaussdb=# SELECT * FROM t1, t2 LIMIT 1; c1 | c1 ----+---- 1 | 1 (1 row) gaussdb=# SELECT query, unique_sql_id FROM dbe_perf.summary_statement WHERE query LIKE '%SELECT * FROM t1, t2 LIMIT%'; query | unique_sql_id -------------------------------+--------------- SELECT * FROM t1, t2 LIMIT ?; | 2763456878 (1 row) gaussdb=# SELECT relname, analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname IN ('t1', 't2'); relname | analyze_count ---------+--------------- t1 | 5 t2 | 3 (2 rows) gaussdb=# SELECT * FROM dbe_stats.analyze_sqlid(2763456878); nspname | tabname ---------+--------- public | t1 public | t2 (2 rows) gaussdb=# SELECT relname, analyze_count FROM pg_stat_all_tables WHERE schemaname = 'public' AND relname IN ('t1', 't2'); relname | analyze_count ---------+--------------- t1 | 6 t2 | 4 (2 rows) -- 后置操作。 gaussdb=# DROP PROCEDURE IF EXISTS select_t1; DROP PROCEDURE gaussdb=# DROP TABLE IF EXISTS t1; DROP TABLE gaussdb=# DROP TABLE IF EXISTS t2; DROP TABLE - dbe_stats_tools.py
- 导出统计信息时,需要具备相应接口或命令(DBE_STATS.CREATE_STAT_TABLE、DBE_STATS.EXPORT_DATABASE_STATS、\COPY TO、DBE_STATS.DROP_STAT_TABLE)的权限,以及指定导出目录的读写权限。
- 导入统计信息时,需要具备相应接口或命令(DBE_STATS.CREATE_STAT_TABLE、DBE_STATS.EXPORT_DATABASE_STATS、\COPY FROM、DBE_STATS.DROP_STAT_TABLE)的权限,以及指定导出目录下文件的读取权限。
- 导出语句元信息的收集项包括:
- 输入的SQL语句文本。
- 在hint生效与不生效场景下,对SQL语句执行EXPLAIN操作得到的信息。
- 所在DATABASE中所有对象的定义。
- 与计划调优相关的所有GUC参数配置,不包含应用的会话级别配置。
- SQL语句所引用表对象的当前统计信息与历史统计信息(仅在生成计划为stream类型时导出此项)。
导出语句元信息时,需要数据库的系统管理员权限,以及指定目录的读写权限。
M-Compatibility兼容模式下不支持该工具。
表32 dbe_stats_tools.py接口参数说明 参数
是否允许为空
描述
--mode/-m
否
取值范围:dump、restore、explain、explain_analyze。
- dump:导出。
- restore:导入。
- explain:导出语句元信息,不实际执行语句。
- explain_analyze:导出语句元信息,实际执行语句。
--database/-d
否
导出或导入的目标数据库名字。
--port/-p
否
数据库CN节点端口号。取值范围是[1, 65535]。
--user/-U
是
用户名,如果不输入-U参数,则会获取当前用户名作为入参。
--passwd/-W
是
用户密码。如果指定该选项,需要单独输入密码。
--host/-H
是
导出或导入目标数据库节点的IP。
--set/-s
是
在语句元信息收集模式下,设置会话级别GUC参数。可指定多次,对应多个GUC参数设置。
--command/-c
否
在语句元信息收集模式下,指定SQL文本。要求是单条可执行EXPLAIN的SQL语句,且不能带有EXPLAIN关键字。explain_analyze模式下仅支持SELECT语句。
--file/-f
否
在语句元信息收集模式下,指定存放SQL文本的文件路径。要求是单条可执行EXPLAIN的SQL语句,且不能带有EXPLAIN关键字。explain_analyze模式下仅支持SELECT语句。
--output/-o
否
存放导出统计信息的目录。
- 统计信息导出后,会在--output参数所指定的目录下生成gs_stats.meta(元数据文件)和gs_stats.csv(指定DATABASE用户表的统计信息文件)。
- 语句元信息导出后,会在--output参数所指定目录下生成以下目录及文件:
- query.sql:存放输入的SQL语句文本。
- metainfo_nohint:该目录默认生成,存放内容是语句无hint生效(当语句本身无hint或工具使其失效)时的信息:
- explain.log:对SQL语句进行EXPLAIN的结果。
- metainfo_hinted:仅当语句有hint生效时生成该目录,内容结构与metainfo_nohint一致。
- objdefs.sql:所在DATABASE中所有对象的定义。
- querytuning.conf:与计划调优相关的所有GUC参数配置,不包含应用的会话级别配置。
- currstats:SQL语句所引用表对象的当前统计信息,目录结构与dump模式的输出一致。
- histstats:SQL语句所引用表对象的历史统计信息,该目录下每一个histstats_<timestamp>子目录对应某个时间戳的统计信息快照,子目录下的文件结构与dump模式的输出一致。histstats下最多拥有50个历史统计信息快照,如果DATABASE中实际查询的快照总数超出该数目,输出的50个历史统计信息快照则为等距采样的结果。
示例一:导出导入统计信息流程。
# 导出统计信息流程示例。 [omm@localhost ~]$ python3 dbe_stats_tools.py -m dump -d db1 -p 8000 --output ./stats export table name: "export_table_1749782634" execute: "gsql -d db1 -p 8000 -U omm -c "select 1 from pg_catalog.pg_class where relname = 'export_table_1749782634' and relnamespace = 2200;"" execute: "gsql -d db1 -p 8000 -U omm -c "START TRANSACTION;call dbe_stats.create_stat_table(ownname => 'public', stattab => 'export_table_1749782634');call dbe_stats.export_database_stats(stattab=>'export_table_1749782634',statown=>'public');\COPY public.export_table_1749782634TO '/home/omm/stats/gs_stats.csv' WITH (FORMAT CSV, HEADER);call dbe_stats.drop_stat_table(ownname => 'public', stattab => 'export_table_1749782634');COMMIT;"" execute: "gsql -d db1 -p 8000 -U omm -c "select pg_catalog.gs_get_current_version() from dual;"" deployment: "M" execute: "gsql -d db1 -p 8000 -U omm -c "select count(1) from pg_catalog.pgxc_node where node_type = 'D';"" datanode number: "6" dump complete! # 导出统计信息后,stats目录下会生成元数据文件和统计信息的dump文件。 [omm@localhost ~]$ ls stats/ gs_stats.csv gs_stats.meta # 导入统计信息流程示例。 [omm@localhost ~]$ python3 dbe_stats_tools.py -m restore -d db1 -p 8000 --output ./stats export table name: "export_table_1749782643" gs_stats meta file: "/home/omm/stats/gs_stats.meta" deployment: "M" execute: "gsql -d db1 -p 8000 -U omm -c "select pg_catalog.gs_get_current_version() from dual;"" datanode number: "6" execute: "gsql -d db1 -p 8000 -U omm -c "select count(1) from pg_catalog.pgxc_node where node_type = 'D';"" execute: "gsql -d db1 -p 8000 -U omm -c "select 1 from pg_catalog.pg_class where relname = 'export_table_1749782643' and relnamespace = 2200;"" execute: "gsql -d db1 -p 8000 -U omm -c "START TRANSACTION;call dbe_stats.create_stat_table(ownname => 'public', stattab => 'export_table_1749782643');\COPY public.export_table_1749782643 FROM '/home/omm/stats/gs_stats.csv' WITH (FORMAT CSV, HEADER);call dbe_stats.import_database_stats(stattab=>'export_table_1749782643',statown=>'public');call dbe_stats.drop_stat_table(ownname => 'public', stattab => 'export_table_1749782643');COMMIT;"" restore complete!
示例二:通过语句元信息复现SQL计划不优问题。本示例包含了一个经典的计划不优问题:在数据变更后,未及时收集统计信息,导致选错索引的计划。
前置操作:建表、插入数据、复现慢SQL业务。
# 示例中使用的db1为ORA-Compatibility兼容模式数据库,请根据实际需要替换数据库名字。 # 示例中执行命令的节点为集群节点。 [omm@localhost ~]$ gsql -d db1 -p 8000 -r -- 1.为避免基数反馈、计划复用、语句下推等对该慢SQL问题复现产生影响,设置以下GUC参数。 db1=# SET enable_feedback_cardest = OFF; SET db1=# SET cursor_sharing = OFF; SET db1=# SET enable_fast_query_shipping = OFF; SET db1=# SET explain_perf_mode = 'pretty'; SET -- 2.预置数据,s表仅用于数据生成,t表是最终查询的业务表。 db1=# DROP TABLE IF EXISTS s; NOTICE: table "s" does not exist, skipping DROP TABLE db1=# CREATE TABLE s ( i INT ) DISTRIBUTE BY HASH (i); CREATE TABLE db1=# INSERT INTO s SELECT generate_series(1, 550000); INSERT 0 550000 db1=# ANALYZE s; ANALYZE db1=# DROP TABLE IF EXISTS t; NOTICE: table "t" does not exist, skipping DROP TABLE db1=# CREATE TABLE t ( idate INT, no INT ) DISTRIBUTE BY HASH (idate) PARTITION BY RANGE (idate) ( PARTITION p1 VALUES LESS THAN (200), PARTITION p2 VALUES LESS THAN (400), PARTITION p3 VALUES LESS THAN (MAXVALUE) ); CREATE TABLE db1=# CREATE INDEX t_i ON t(idate) LOCAL; CREATE INDEX db1=# CREATE INDEX t_no ON t(no) LOCAL; CREATE INDEX db1=# INSERT INTO t SELECT floor(random() * 540) AS idate, floor(random() * 30) AS no FROM s WHERE i <= 540000; INSERT 0 540000 db1=# ANALYZE t; ANALYZE -- 3.插入新数据,但是不重新执行ANALYZE。 db1=# INSERT INTO t SELECT floor(540 + random() * 10) AS idate, floor(random() * 30) AS no FROM s WHERE i <= 1000000; INSERT 0 550000 -- 4.查询新增部分数据(默认计划 vs hint计划)。 db1=# EXPLAIN ANALYZE SELECT * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1; id | operation | A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs ----+----------------------------------------------+-------------------+--------+--------+-------------+---------+---------+--------- 1 | -> Streaming (type: GATHER) | 144.711 | 18204 | 1 | 81KB | | 8 | 2.60 2 | -> Partitioned Index Scan using t_i on t | [100.696,130.653] | 18204 | 1 | [78KB,78KB] | | 8 | 2.47 (2 rows) Predicate Information (identified by plan id) -------------------------------------------------------- 2 --Partitioned Index Scan using t_i on t Index Cond: ((idate >= 540) AND (idate < 550)) Filter: (no = 1) Rows Removed by Filter: 531796 Selected Partitions: 3 (5 rows) Memory Information (identified by plan id) -------------------------------------------- Coordinator Query Peak Memory: Query Peak Memory: 1MB Datanode: Max Query Peak Memory: 0MB Min Query Peak Memory: 0MB (5 rows) User Define Profiling --------------------------------------------------------------------------- Plan Node id: 1 Track name: coordinator get datanode connection (actual time=[0.062, 0.062], calls=[1, 1]) Plan Node id: 1 Track name: Coordinator serialize plan (actual time=[1.085, 1.085], calls=[1, 1]) Plan Node id: 1 Track name: Coordinator send begin command (actual time=[0.003, 0.003], calls=[1, 1]) Plan Node id: 1 Track name: Coordinator start transaction and send query (actual time=[0.053, 0.053], calls=[1, 1]) (8 rows) ====== Query Summary ===== -------------------------------------------------------------------------------------------- Datanode executor start time [dn_6001_6002_6003, dn_6004_6005_6006]: [0.229 ms,0.261 ms] Datanode executor run time [dn_6007_6008_6009, dn_6001_6002_6003]: [111.230 ms,144.077 ms] Datanode executor end time [dn_6004_6005_6006, dn_6001_6002_6003]: [0.012 ms,0.022 ms] Coordinator executor start time: 0.095 ms Coordinator executor run time: 146.583 ms Coordinator executor end time: 0.044 ms Planner runtime: 0.474 ms Plan size: 3857 byte Query Id: 72339069015809757 Total runtime: 146.743 ms (10 rows) db1=# EXPLAIN ANALYZE SELECT /*+ indexscan(t t_no) */ * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1; id | operation | A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs ----+-----------------------------------------------+---------------+--------+--------+-------------+---------+---------+--------- 1 | -> Streaming (type: GATHER) | 25.360 | 18204 | 17652 | 81KB | | 8 | 4265.30 2 | -> Partitioned Index Scan using t_no on t | [5.622,8.476] | 18204 | 17652 | [78KB,78KB] | | 8 | 3529.80 (2 rows) Predicate Information (identified by plan id) ---------------------------------------------------- 2 --Partitioned Index Scan using t_no on t Index Cond: (no = 1) Filter: ((idate >= 540) AND (idate < 550)) Rows Removed by Filter: 4554 Selected Partitions: 3 (5 rows) Memory Information (identified by plan id) -------------------------------------------- Coordinator Query Peak Memory: Query Peak Memory: 1MB Datanode: Max Query Peak Memory: 0MB Min Query Peak Memory: 0MB (5 rows) User Define Profiling --------------------------------------------------------------------------- Plan Node id: 1 Track name: coordinator get datanode connection (actual time=[0.812, 0.812], calls=[1, 1]) Plan Node id: 1 Track name: Coordinator serialize plan (actual time=[1.924, 1.924], calls=[1, 1]) Plan Node id: 1 Track name: Coordinator send begin command (actual time=[0.003, 0.003], calls=[1, 1]) Plan Node id: 1 Track name: Coordinator start transaction and send query (actual time=[0.058, 0.058], calls=[1, 1]) (8 rows) ====== Query Summary ===== ------------------------------------------------------------------------------------------ Datanode executor start time [dn_6004_6005_6006, dn_6007_6008_6009]: [0.397 ms,0.584 ms] Datanode executor run time [dn_6004_6005_6006, dn_6007_6008_6009]: [12.902 ms,21.639 ms] Datanode executor end time [dn_6004_6005_6006, dn_6007_6008_6009]: [0.011 ms,0.019 ms] Coordinator executor start time: 0.165 ms Coordinator executor run time: 26.601 ms Coordinator executor end time: 0.038 ms Planner runtime: 1.037 ms Plan size: 3886 byte Query Id: 72339069015811437 Total runtime: 26.853 ms (10 rows) db1=# \q场景一:通过-c选项收集带HINT SQL语句的元信息,对比HINT生效与不生效情况下的计划信息。
# 指定带hint的SQL文本,收集其元信息。 [omm@localhost ~]$ rm -rf ./hint_metainfo [omm@localhost ~]$ python3 $GAUSSHOME/bin/dbe_stats_tools.py -m explain_analyze -d db1 -p 8000 -s enable_fast_query_shipping=off -c 'SELECT /*+ indexscan(t t_no) */ * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1;' -o ./hint_metainfo execute: "gsql -d db1 -p 8000 -U omm -q -f - START TRANSACTION READ ONLY; set enable_fast_query_shipping=E'off'; set explain_perf_mode = pretty; set cursor_sharing = off; explain (metadata on, tables on, analyze on) SELECT /*+ indexscan(t t_no) */ * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1; ROLLBACK;" execute: "gsql -d db1 -p 8000 -U omm -q -f - START TRANSACTION READ ONLY; set enable_fast_query_shipping=E'off'; set explain_perf_mode = pretty; set cursor_sharing = off; set parser_ignore_hints = on; explain (metadata on, tables on, analyze on) SELECT /*+ indexscan(t t_no) */ * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1; ROLLBACK;" explaining query completed! dumping query tuning settings completed! dumping object definition completed! dumping current statistics completed! dumping historical statistics completed! # 此时得到该语句在hint生效与不生效时的计划信息,以及其它可用于复现的信息。 [omm@localhost ~]$ ls -R ./hint_metainfo/ ./hint_metainfo/: currstats histstats metainfo_hinted metainfo_nohint objdefs.sql query.sql querytuning.conf ./hint_metainfo/currstats: gs_stats.csv gs_stats.meta ./hint_metainfo/histstats: histstats_2026-07-21_15:34:04.161597+08 histstats_2026-07-21_15:35:43.781149+08 histstats_2026-07-21_15:35:43.970977+08 histstats_2026-07-21_15:35:44.108525+08 histstats_2026-07-21_15:35:44.255638+08 './hint_metainfo/histstats/histstats_2026-07-21_15:34:04.161597+08': gs_stats.csv gs_stats.meta './hint_metainfo/histstats/histstats_2026-07-21_15:35:43.781149+08': gs_stats.csv gs_stats.meta './hint_metainfo/histstats/histstats_2026-07-21_15:35:43.970977+08': gs_stats.csv gs_stats.meta './hint_metainfo/histstats/histstats_2026-07-21_15:35:44.108525+08': gs_stats.csv gs_stats.meta './hint_metainfo/histstats/histstats_2026-07-21_15:35:44.255638+08': gs_stats.csv gs_stats.meta ./hint_metainfo/metainfo_hinted: explain.log ./hint_metainfo/metainfo_nohint: explain.log
场景二:通过-f选项收集对应语句的元信息,并尝试在测试库中复现当前与历史执行计划。
# 通过gsql连接,对t表执行ANALYZE,更新其统计信息。 [omm@localhost ~]$ gsql -d db1 -p 8000 -r db1=# SET enable_feedback_cardest = OFF; SET db1=# SET cursor_sharing = OFF; SET db1=# SET enable_fast_query_shipping = OFF; SET db1=# SET explain_perf_mode = 'pretty'; SET -- 执行ANALYZE解决慢SQL问题。 db1=# ANALYZE t; ANALYZE -- 重新收集统计信息后,计划默认最优。 db1=# EXPLAIN ANALYZE SELECT * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1; id | operation | A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs ----+----------------------------------------------------+---------------+--------+--------+---------------+---------+---------+--------- 1 | -> Streaming (type: GATHER) | 25.861 | 18204 | 18636 | 82KB | | 8 | 4204.50 2 | -> Partitioned Bitmap Heap Scan on t | [8.731,9.053] | 18204 | 18636 | [23KB,23KB] | | 8 | 3428.00 3 | -> Partitioned Bitmap Index Scan using t_no | [1.066,1.100] | 22758 | 23400 | [178KB,200KB] | | 0 | 60.95 (3 rows) Predicate Information (identified by plan id) ---------------------------------------------------- 2 --Partitioned Bitmap Heap Scan on t Recheck Cond: (no = 1) Filter: ((idate >= 540) AND (idate < 550)) Rows Removed by Filter: 4554 Selected Partitions: 3 3 --Partitioned Bitmap Index Scan using t_no Index Cond: (no = 1) (7 rows) Memory Information (identified by plan id) -------------------------------------------- Coordinator Query Peak Memory: Query Peak Memory: 1MB Datanode: Max Query Peak Memory: 0MB Min Query Peak Memory: 0MB (5 rows) User Define Profiling --------------------------------------------------------------------------- Plan Node id: 1 Track name: coordinator get datanode connection (actual time=[1.722, 1.722], calls=[1, 1]) Plan Node id: 1 Track name: Coordinator serialize plan (actual time=[1.236, 1.236], calls=[1, 1]) Plan Node id: 1 Track name: Coordinator send begin command (actual time=[0.003, 0.003], calls=[1, 1]) Plan Node id: 1 Track name: Coordinator start transaction and send query (actual time=[0.048, 0.048], calls=[1, 1]) (8 rows) ====== Query Summary ===== ------------------------------------------------------------------------------------------ Datanode executor start time [dn_6001_6002_6003, dn_6007_6008_6009]: [0.388 ms,0.550 ms] Datanode executor run time [dn_6001_6002_6003, dn_6007_6008_6009]: [19.315 ms,22.296 ms] Datanode executor end time [dn_6004_6005_6006, dn_6007_6008_6009]: [0.022 ms,0.033 ms] Coordinator executor start time: 0.113 ms Coordinator executor run time: 27.502 ms Coordinator executor end time: 0.032 ms Planner runtime: 0.594 ms Plan size: 3924 byte Query Id: 72339069015818205 Total runtime: 27.669 ms (10 rows) db1=# \q # 通过指定SQL文本文件的方式,收集语句元信息。 [omm@localhost ~]$ echo 'SELECT * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1;' > ./tmp.sql [omm@localhost ~]$ python3 $GAUSSHOME/bin/dbe_stats_tools.py -m explain_analyze -d db1 -p 8000 -s enable_fast_query_shipping=off -f ./tmp.sql -o ./hist_metainfo execute: "gsql -d db1 -p 8000 -U omm -q -f - START TRANSACTION READ ONLY; set enable_fast_query_shipping=E'off'; set explain_perf_mode = pretty; set cursor_sharing = off; explain (metadata on, tables on, analyze on) SELECT * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1; ROLLBACK;" explaining query completed! dumping query tuning settings completed! dumping object definition completed! dumping current statistics completed! dumping historical statistics completed! # 此时导出的语句元信息有多个历史统计信息快照。 [omm@localhost ~]$ ls -R ./hist_metainfo ./hist_metainfo: currstats histstats metainfo_nohint objdefs.sql query.sql querytuning.conf ./hist_metainfo/currstats: gs_stats.csv gs_stats.meta ./hist_metainfo/histstats: histstats_2026-07-21_15:34:04.161597+08 histstats_2026-07-21_15:35:43.970977+08 histstats_2026-07-21_15:35:44.255638+08 histstats_2026-07-21_15:35:43.781149+08 histstats_2026-07-21_15:35:44.108525+08 histstats_2026-07-21_15:38:27.837751+08 './hist_metainfo/histstats/histstats_2026-07-21_15:34:04.161597+08': gs_stats.csv gs_stats.meta './hist_metainfo/histstats/histstats_2026-07-21_15:35:43.781149+08': gs_stats.csv gs_stats.meta './hist_metainfo/histstats/histstats_2026-07-21_15:35:43.970977+08': gs_stats.csv gs_stats.meta './hist_metainfo/histstats/histstats_2026-07-21_15:35:44.108525+08': gs_stats.csv gs_stats.meta './hist_metainfo/histstats/histstats_2026-07-21_15:35:44.255638+08': gs_stats.csv gs_stats.meta './hist_metainfo/histstats/histstats_2026-07-21_15:38:27.837751+08': gs_stats.csv gs_stats.meta ./hist_metainfo/metainfo_nohint: explain.log # 创建一个测试库,导入对象定义与统计信息。 [omm@localhost ~]$ gsql -d postgres -p 8000 -c 'DROP DATABASE IF EXISTS db_test;' NOTICE: database "db_test" does not exist, skipping DROP DATABASE [omm@localhost ~]$ gsql -d postgres -p 8000 -c "CREATE DATABASE db_test WITH dbcompatibility = 'ORA';" CREATE DATABASE [omm@localhost ~]$ gsql -d db_test -p 8000 -q -f ./hist_metainfo/objdefs.sql total time: 386 ms # 先尝试导入当前统计信息,复现修复后的执行计划。 [omm@localhost ~]$ python3 $GAUSSHOME/bin/dbe_stats_tools.py -m restore -d db_test -p 8000 --output ./hist_metainfo/currstats export table name: "export_table_1784619829" execute: "gsql -d db_test -p 8000 -U omm -q -f - select pg_catalog.gs_get_current_version() from dual;" gs_stats meta file: "/home/omm/hist_metainfo/currstats/gs_stats.meta" deployment: "M" datanode number: "3" execute: "gsql -d db_test -p 8000 -U omm -q -f - select pg_catalog.count(1) from pg_catalog.pgxc_node where node_type = 'D';" execute: "gsql -d db_test -p 8000 -U omm -q -f - select 1 from pg_catalog.pg_class where relname = 'export_table_1784619829' and relnamespace = 2200;" execute: "gsql -d db_test -p 8000 -U omm -q -f - START TRANSACTION;call dbe_stats.create_stat_table(ownname => 'public', stattab => 'export_table_1784619829');\COPY public.export_table_1784619829 FROM '/home/omm/hist_metainfo/currstats/gs_stats.csv' WITH (FORMAT CSV, HEADER);call dbe_stats.import_database_stats(stattab=>'export_table_1784619829',statown=>'public');call dbe_stats.drop_stat_table(ownname => 'public', stattab => 'export_table_1784619829');COMMIT;" restore complete! [omm@localhost ~]$ gsql -d db_test -p 8000 -c "SET cursor_sharing = OFF; SET enable_fast_query_shipping = OFF; SET enable_feedback_cardest = OFF; SET explain_perf_mode = 'pretty'; EXPLAIN SELECT * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1;" SET SET SET SET id | operation | E-rows | E-width | E-costs ----+----------------------------------------------------+--------+---------+--------- 1 | -> Streaming (type: GATHER) | 18636 | 8 | 4204.50 2 | -> Partitioned Bitmap Heap Scan on t | 18636 | 8 | 3428.00 3 | -> Partitioned Bitmap Index Scan using t_no | 23400 | 0 | 60.95 (3 rows) Predicate Information (identified by plan id) ---------------------------------------------------- 2 --Partitioned Bitmap Heap Scan on t Recheck Cond: (no = 1) Filter: ((idate >= 540) AND (idate < 550)) Selected Partitions: 3 3 --Partitioned Bitmap Index Scan using t_no Index Cond: (no = 1) (6 rows) # 再尝试导入历史统计信息,复现修复前的执行计划(选择最接近问题发生时的时间戳)。 [omm@localhost ~]$ python3 $GAUSSHOME/bin/dbe_stats_tools.py -m restore -d db_test -p 8000 --output ./hist_metainfo/histstats/histstats_2026-07-21_15\:34\:04.161597+08 export table name: "export_table_1784620247" execute: "gsql -d db_test -p 8000 -U omm -q -f - select pg_catalog.gs_get_current_version() from dual;" gs_stats meta file: "/home/omm/hist_metainfo/histstats/histstats_2026-07-21_15:34:04.161597+08/gs_stats.meta" deployment: "M" datanode number: "3" execute: "gsql -d db_test -p 8000 -U omm -q -f - select pg_catalog.count(1) from pg_catalog.pgxc_node where node_type = 'D';" execute: "gsql -d db_test -p 8000 -U omm -q -f - select 1 from pg_catalog.pg_class where relname = 'export_table_1784620247' and relnamespace = 2200;" execute: "gsql -d db_test -p 8000 -U omm -q -f - START TRANSACTION;call dbe_stats.create_stat_table(ownname => 'public', stattab => 'export_table_1784620247');\COPY public.export_table_1784620247 FROM '/home/omm/hist_metainfo/histstats/histstats_2026-07-21_15:34:04.161597+08/gs_stats.csv' WITH (FORMAT CSV, HEADER);call dbe_stats.import_database_stats(stattab=>'export_table_1784620247',statown=>'public');call dbe_stats.drop_stat_table(ownname => 'public', stattab => 'export_table_1784620247');COMMIT;" restore complete! [omm@localhost ~]$ gsql -d db_test -p 8000 -c 'SET cursor_sharing = OFF; SET enable_fast_query_shipping = OFF; SET enable_feedback_cardest = OFF; SET explain_perf_mode = 'pretty'; EXPLAIN SELECT * FROM t WHERE idate >= 540 AND idate < 550 AND no = 1;' SET SET SET SET id | operation | E-rows | E-width | E-costs ----+----------------------------------------------+--------+---------+--------- 1 | -> Streaming (type: GATHER) | 1 | 8 | 2.60 2 | -> Partitioned Index Scan using t_i on t | 1 | 8 | 2.47 (2 rows) Predicate Information (identified by plan id) -------------------------------------------------------- 2 --Partitioned Index Scan using t_i on t Index Cond: ((idate >= 540) AND (idate < 550)) Filter: (no = 1) Selected Partitions: 3 (4 rows)后置操作:清理数据库对象与导出目录文件。
# 清理数据库对象。 [omm@localhost ~]$ gsql -d db1 -p 8000 -r db1=# DROP TABLE s CASCADE; DROP TABLE db1=# DROP TABLE t CASCADE; DROP TABLE db1=# DROP DATABASE db_test; DROP DATABASE db1=# \q # 清理导出文件。 [omm@localhost ~]$ rm -rf ./hint_metainfo [omm@localhost ~]$ rm -rf ./hist_metainfo