[2023-04-18]增量收集统计信息

在11g之前,收集global的统计信息时,oracle需要扫描每个分区的统计信息,才能得出 global的统计信息。而在11g以后,Oracle会简单记录分区的概要信息,(synopsis,记录在 WRI$_OPTSTAT_SYNOPSIS_HEAD$ 和 WRI$_OPTSTAT_SYNOPSIS$中),对于global的统计信息,可以不再扫描每个分区的,只需通过计算概要信息,即可得出global 的统计信息。

1、创建分区表

SQL> create table p(id number, age date)
  2  partition by range(id)
  3  (partition p1 values less than(100),
  4  partition p2 values less than(200),
  5  partition p3 values less than(300),
  6  partition p4 values less than(400)
  7  );

Table created.

SQL> insert into p select level lv,sysdate from dual connect by level < 400;

399 rows created.

SQL> commit;

Commit complete.

SQL> exec dbms_stats.gather_table_stats(ownname=>'scott',tabname=>'p');

PL/SQL procedure successfully completed.

SQL>  select table_owner,table_name,partition_name from dba_tab_partitions where table_owner='SCOTT' and table_name='P';

TABLE_OWNER                    TABLE_NAME                     PARTITION_NAME
------------------------------ ------------------------------ ------------------------------
SCOTT                          P                              P1
SCOTT                          P                              P2
SCOTT                          P                              P3
SCOTT                          P                              P4


SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';

Session altered.

SQL> select table_name,num_rows,last_analyzed from dba_tables where table_name='P';

TABLE_NAME                       NUM_ROWS LAST_ANALYZED
------------------------------ ---------- -------------------
P                                     399 2023-04-18 16:33:47

SQL> 
SQL>   select table_name,partition_name,num_rows,last_analyzed from dba_tab_partitions where table_name='P';

TABLE_NAME                     PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ------------------------------ ---------- -------------------
P                              P1                                     99 2023-04-18 16:33:46
P                              P2                                    100 2023-04-18 16:33:47
P                              P3                                    100 2023-04-18 16:33:47
P                              P4                                    100 2023-04-18 16:33:47

 2、重新收集统计信息

SQL> exec dbms_stats.gather_table_stats(ownname=>'scott',tabname=>'p');

PL/SQL procedure successfully completed.

SQL> select table_name,num_rows,last_analyzed from dba_tables where table_name='P';

TABLE_NAME                       NUM_ROWS LAST_ANALYZED
------------------------------ ---------- -------------------
P                                     399 2023-04-18 16:35:12

SQL> select table_name,partition_name,num_rows,last_analyzed from dba_tab_partitions where table_name='P';

TABLE_NAME                     PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ------------------------------ ---------- -------------------
P                              P1                                     99 2023-04-18 16:35:12
P                              P2                                    100 2023-04-18 16:35:12
P                              P3                                    100 2023-04-18 16:35:12
P                              P4                                    100 2023-04-18 16:35:12

SQL> 

对表收集统计信息,虽然分区中的数据没有变化,依然会收集全部统计信息。

3、开启增量统计信息的条件

SQL> set lin 300
SQL> col "publish" for a30
SQL> col "granularity" for a30
SQL> col "incremental" for a30
SQL> select 
  2  dbms_stats.get_prefs('publish','&owner','&tablename') "publish",
  3  dbms_stats.get_prefs('granularity','&&owner','&&tablename') "granularity",
  4  dbms_stats.get_prefs('INCREMENTAL','&&owner','&&tablename') "incremental" 
  5  from dual;
Enter value for owner: scott
Enter value for tablename: p
old   2: dbms_stats.get_prefs('publish','&owner','&tablename') "publish",
new   2: dbms_stats.get_prefs('publish','scott','p') "publish",
Enter value for owner: scott
Enter value for tablename: p
old   3: dbms_stats.get_prefs('granularity','&&owner','&&tablename') "granularity",
new   3: dbms_stats.get_prefs('granularity','scott','p') "granularity",
old   4: dbms_stats.get_prefs('INCREMENTAL','&&owner','&&tablename') "incremental"
new   4: dbms_stats.get_prefs('INCREMENTAL','scott','p') "incremental"

publish                        granularity                    incremental
------------------------------ ------------------------------ ------------------------------
TRUE                           AUTO                           FALSE

SQL> 
SQL> exec dbms_stats.set_table_prefs('SCOTT', 'P', 'INCREMENTAL', 'TRUE');

PL/SQL procedure successfully completed.

SQL> col "publish" for a30
SQL> col "granularity" for a30
SQL> col "incremental" for a30
SQL> select 
  2  dbms_stats.get_prefs('publish','&owner','&tablename') "publish",
  3  dbms_stats.get_prefs('granularity','&&owner','&&tablename') "granularity",
  4  dbms_stats.get_prefs('INCREMENTAL','&&owner','&&tablename') "incremental" 
  5  from dual;
old   2: dbms_stats.get_prefs('publish','&owner','&tablename') "publish",
new   2: dbms_stats.get_prefs('publish','scott','p') "publish",
old   3: dbms_stats.get_prefs('granularity','&&owner','&&tablename') "granularity",
new   3: dbms_stats.get_prefs('granularity','scott','p') "granularity",
old   4: dbms_stats.get_prefs('INCREMENTAL','&&owner','&&tablename') "incremental"
new   4: dbms_stats.get_prefs('INCREMENTAL','scott','p') "incremental"

publish                        granularity                    incremental
------------------------------ ------------------------------ ------------------------------
TRUE                           AUTO                           TRUE

SQL> 

4、开启增量后第一次收集统计信息

SQL> exec dbms_stats.gather_table_stats(ownname=>'scott',tabname=>'p');

PL/SQL procedure successfully completed.

SQL> select table_name,num_rows,last_analyzed from dba_tables where table_name='P';

TABLE_NAME                       NUM_ROWS LAST_ANALYZED
------------------------------ ---------- -------------------
P                                     399 2023-04-18 16:39:26

SQL> select table_name,partition_name,num_rows,last_analyzed from dba_tab_partitions where table_name='P';

TABLE_NAME                     PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ------------------------------ ---------- -------------------
P                              P1                                     99 2023-04-18 16:39:26
P                              P2                                    100 2023-04-18 16:39:26
P                              P3                                    100 2023-04-18 16:39:26
P                              P4                                    100 2023-04-18 16:39:26

SQL> 

设置增量收集后,第一次收集统计信息会将全部历史分区重新收集,以生成历史分区的大纲信息,分区数越多,耗时越长

5、开启增量后第二次收集统计信息

SQL> exec dbms_stats.gather_table_stats(ownname=>'scott',tabname=>'p');

PL/SQL procedure successfully completed.

SQL> select table_name,num_rows,last_analyzed from dba_tables where table_name='P';

TABLE_NAME                       NUM_ROWS LAST_ANALYZED
------------------------------ ---------- -------------------
P                                     399 2023-04-18 16:41:03

SQL> select table_name,partition_name,num_rows,last_analyzed from dba_tab_partitions where table_name='P';

TABLE_NAME                     PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ------------------------------ ---------- -------------------
P                              P1                                     99 2023-04-18 16:39:26
P                              P2                                    100 2023-04-18 16:39:26
P                              P3                                    100 2023-04-18 16:39:26
P                              P4                                    100 2023-04-18 16:39:26

SQL> 

全局统计信息时间更新了,但是分区统计信息还是旧的。

6、对某个分区收集统计信息,全局统计信息也会更新

SQL> exec dbms_stats.gather_table_stats(ownname=>'scott',tabname=>'p',PARTNAME=>'p1');

PL/SQL procedure successfully completed.

SQL> select table_name,num_rows,last_analyzed from dba_tables where table_name='P';

TABLE_NAME                       NUM_ROWS LAST_ANALYZED
------------------------------ ---------- -------------------
P                                     399 2023-04-18 16:42:26

SQL> select table_name,partition_name,num_rows,last_analyzed from dba_tab_partitions where table_name='P';

TABLE_NAME                     PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ------------------------------ ---------- -------------------
P                              P1                                     99 2023-04-18 16:42:26
P                              P2                                    100 2023-04-18 16:39:26
P                              P3                                    100 2023-04-18 16:39:26
P                              P4                                    100 2023-04-18 16:39:26

SQL> 


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
针对Oracle分区表的收集统计信息可以通过以下步骤完成: 1. 确定需要收集统计信息的分区表。 2. 使用DBMS_STATS包中的GATHER_TABLE_STATS过程收集表的统计信息。例如: ``` EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>'schema_name',tabname=>'table_name',partname=>'partition_name',cascade=>TRUE,estimate_percent=>DBMS_STATS.AUTO_SAMPLE_SIZE); ``` 其中,ownname代表分区表所在的schema名称,tabname代表分区表名称,partname代表分区名称,cascade参数指定收集分区表的所有分区的统计信息,estimate_percent参数指定使用自动样本大小。 3. 对于大型分区表,可以考虑使用INCREMENTAL方法收集统计信息,以便节省收集统计信息的时间和资源。例如: ``` EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>'schema_name',tabname=>'table_name',partname=>'partition_name',cascade=>TRUE,estimate_percent=>DBMS_STATS.AUTO_SAMPLE_SIZE,method_opt=>'FOR ALL COLUMNS SIZE AUTO INCREMENTAL ON PARTITION(partition_name)'); ``` 其中,method_opt参数指定了使用INCREMENTAL方法收集统计信息,并且只对指定的分区进行增量收集。 4. 在收集完分区表的统计信息后,可以使用DBMS_STATS.PURGE_TABLE_STATS过程清除过期的统计信息。例如: ``` EXEC DBMS_STATS.PURGE_TABLE_STATS(ownname=>'schema_name',tabname=>'table_name',partname=>'partition_name',cascade=>TRUE); ``` 其中,cascade参数指定清除分区表的所有分区的统计信息。 以上就是收集Oracle分区表统计信息的基本步骤。需要注意的是,统计信息收集频率应该根据分区表数据的变化情况来确定,以便保证查询优化器的准确性和性能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值