Oracle 分区表收集分区统计信息、索引信息

--删除表
DROP TABLE TEST3;

--1.创建按日分区测试表
CREATE TABLE TEST3(ID INT, PARDATE DATE)
PARTITION BY RANGE (PARDATE) INTERVAL (NUMTODSINTERVAL (1,'DAY'))
(
  PARTITION P_20180101 VALUES LESS THAN (TO_DATE('2018-01-02', 'YYYY-MM-DD'))
);
表已创建。

--2.插入2天的数据,每天100条数据
INSERT INTO TEST3
SELECT ROWNUM,TO_DATE('20210324','YYYYMMDD') FROM DBA_OBJECTS WHERE ROWNUM <= 100;
INSERT INTO TEST3
SELECT ROWNUM,TO_DATE('20210325','YYYYMMDD') FROM DBA_OBJECTS WHERE ROWNUM <= 100;
COMMIT;

--3.模拟生产,先收集下全局统计信息,避免动态采集
EXEC DBMS_STATS.GATHER_TABLE_STATS(USER,'TEST3');

--查看分区统计信息
set linesize 200
col PARTITION_NAME for a30
SELECT P.PARTITION_NAME, P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TAB_PARTITIONS P
 WHERE TABLE_NAME = 'TEST3';
 
PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ---------- ---------------
P_20180101                              0 03-SEP-22
SYS_P903                              100 03-SEP-22
SYS_P904                              100 03-SEP-22

--查看全局统计信息
SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';

  NUM_ROWS LAST_ANALYZED
---------- ---------------
       200 03-SEP-22 
 
--4.继续插入3天的数据,每天100条数据
INSERT INTO TEST3
SELECT ROWNUM,TO_DATE('20210326','YYYYMMDD') FROM DBA_OBJECTS WHERE ROWNUM <= 100;
INSERT INTO TEST3
SELECT ROWNUM,TO_DATE('20210327','YYYYMMDD') FROM DBA_OBJECTS WHERE ROWNUM <= 100;
INSERT INTO TEST3
SELECT ROWNUM,TO_DATE('20210328','YYYYMMDD') FROM DBA_OBJECTS WHERE ROWNUM <= 100;
COMMIT;

--查看分区统计信息
set linesize 200
col PARTITION_NAME for a30
SELECT P.PARTITION_NAME, P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TAB_PARTITIONS P
 WHERE TABLE_NAME = 'TEST3';

PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ---------- ---------------
P_20180101                              0 03-SEP-22
SYS_P903                              100 03-SEP-22
SYS_P904                              100 03-SEP-22
SYS_P905
SYS_P906
SYS_P907

6 rows selected.

--查看全局统计信息
SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';

  NUM_ROWS LAST_ANALYZED
---------- ---------------
       200 03-SEP-22 

--3.仅收集新增partition的统计信息
-----exec DBMS_STATS.GATHER_TABLE_STATS(ownname => 'AML',tabname => 'T2A_TRANS',partname => 'PT_20220214',granularity => 'PARTITION',estimate_percent => 0.001,degree =>10);
exec dbms_stats.gather_table_stats(user,'TEST3',partname => 'SYS_P905',granularity => 'PARTITION');
exec dbms_stats.gather_table_stats(user,'TEST3',partname => 'SYS_P906',granularity => 'PARTITION');
exec dbms_stats.gather_table_stats(user,'TEST3',partname => 'SYS_P907',granularity => 'PARTITION');

--4.查看分区的统计信息
set linesize 200
col PARTITION_NAME for a30
SELECT P.PARTITION_NAME, P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TAB_PARTITIONS P
 WHERE TABLE_NAME = 'TEST3';
 
PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ---------- ---------------
P_20180101                              0 03-SEP-22
SYS_P903                              100 03-SEP-22
SYS_P904                              100 03-SEP-22
SYS_P905                              100 03-SEP-22
SYS_P906                              100 03-SEP-22
SYS_P907                              100 03-SEP-22

6 rows selected.

--5.查看全局的统计信息, 发现全局统计信息仍陈旧(200条)
SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';
 
  NUM_ROWS LAST_ANALYZED
---------- ---------------
       200 02-SEP-22
 
--6.查看oracle预估返回行数是否正确,单分区准确,跨分区就不准确
set autotrace traceonly
SELECT COUNT(*)
  FROM TEST3
 WHERE PARDATE = TO_DATE('20210326', 'YYYYMMDD');
-------------------------------------------------------------------------------------------------
| Id  | Operation               | Name  | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |       |     1 |     8 |     3   (0)| 00:00:01 |       |       |
|   1 |  SORT AGGREGATE         |       |     1 |     8 |            |          |       |       |
|   2 |   PARTITION RANGE SINGLE|       |   100 |   800 |     3   (0)| 00:00:01 |  1181 |  1181 |
|*  3 |    TABLE ACCESS FULL    | TEST3 |   100 |   800 |     3   (0)| 00:00:01 |  1181 |  1181 |
-------------------------------------------------------------------------------------------------
SELECT COUNT(*)
  FROM TEST3
 WHERE PARDATE = TO_DATE('20210327', 'YYYYMMDD');
-------------------------------------------------------------------------------------------------
| Id  | Operation               | Name  | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |       |     1 |     8 |     3   (0)| 00:00:01 |       |       |
|   1 |  SORT AGGREGATE         |       |     1 |     8 |            |          |       |       |
|   2 |   PARTITION RANGE SINGLE|       |   100 |   800 |     3   (0)| 00:00:01 |  1182 |  1182 |
|*  3 |    TABLE ACCESS FULL    | TEST3 |   100 |   800 |     3   (0)| 00:00:01 |  1182 |  1182 |
-------------------------------------------------------------------------------------------------

--跨分区统计信息就不准确
SELECT COUNT(*)
  FROM TEST3
 WHERE PARDATE IN
       (TO_DATE('20210326', 'YYYYMMDD'), TO_DATE('20210327', 'YYYYMMDD'));
-------------------------------------------------------------------------------------------------
| Id  | Operation               | Name  | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |       |     1 |     8 |     4   (0)| 00:00:01 |       |       |
|   1 |  SORT AGGREGATE         |       |     1 |     8 |            |          |       |       |
|   2 |   PARTITION RANGE INLIST|       |     1 |     8 |     4   (0)| 00:00:01 |KEY(I) |KEY(I) |
|*  3 |    TABLE ACCESS FULL    | TEST3 |     1 |     8 |     4   (0)| 00:00:01 |KEY(I) |KEY(I) |
-------------------------------------------------------------------------------------------------
 
--7.新插入两个分区数据,
INSERT INTO TEST3
SELECT ROWNUM,TO_DATE('20210329','YYYYMMDD') FROM DBA_OBJECTS WHERE ROWNUM <= 100;
INSERT INTO TEST3
SELECT ROWNUM,TO_DATE('20210330','YYYYMMDD') FROM DBA_OBJECTS WHERE ROWNUM <= 100;
COMMIT ;

--查看分区统计信息
set linesize 200
col PARTITION_NAME for a30
SELECT P.PARTITION_NAME, P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TAB_PARTITIONS P
 WHERE TABLE_NAME = 'TEST3';

PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ---------- ---------------
P_20180101                              0 03-SEP-22
SYS_P903                              100 03-SEP-22
SYS_P904                              100 03-SEP-22
SYS_P905                              100 03-SEP-22
SYS_P906                              100 03-SEP-22
SYS_P907                              100 03-SEP-22
SYS_P908
SYS_P909

8 rows selected.

--查看全局统计信息
SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';

  NUM_ROWS LAST_ANALYZED
---------- ---------------
       200 03-SEP-22 

--8.采用AUTO收集,仅收集增加的一个分区统计信息,另外一个不收集
exec dbms_stats.gather_table_stats(user,'TEST3',partname => 'SYS_P908',granularity => 'AUTO');
 
--9.查看分区的统计信息(SYS_P265为空)
set linesize 200
col PARTITION_NAME for a30
SELECT P.PARTITION_NAME, P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TAB_PARTITIONS P
 WHERE TABLE_NAME = 'TEST3';
 
PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ---------- ---------------
P_20180101                              0 03-SEP-22
SYS_P903                              100 03-SEP-22
SYS_P904                              100 03-SEP-22
SYS_P905                              100 03-SEP-22
SYS_P906                              100 03-SEP-22
SYS_P907                              100 03-SEP-22
SYS_P908                              100 03-SEP-22
SYS_P909

8 rows selected.

--查看全局统计信息
SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';

  NUM_ROWS LAST_ANALYZED
---------- ---------------
       700 03-SEP-22


--10.查看全局统计信息,发现条数为700条。意味着全局统计信息不仅仅是将新收集分区的统计信息直接加到全局上去,而是重新全部收集了。
SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';
 
  NUM_ROWS LAST_ANALYZED
---------- ---------------
       700 03-SEP-22

--收集掉另外一个分区再继续测试
exec dbms_stats.gather_table_stats(user,'TEST3',partname => 'SYS_P909',granularity => 'AUTO');

--查看分区统计信息
set linesize 200
col PARTITION_NAME for a30
SELECT P.PARTITION_NAME, P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TAB_PARTITIONS P
 WHERE TABLE_NAME = 'TEST3';

PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ---------- ---------------
P_20180101                              0 03-SEP-22
SYS_P903                              100 03-SEP-22
SYS_P904                              100 03-SEP-22
SYS_P905                              100 03-SEP-22
SYS_P906                              100 03-SEP-22
SYS_P907                              100 03-SEP-22
SYS_P908                              100 03-SEP-22
SYS_P909                              100 03-SEP-22

8 rows selected.

--查看全局统计信息
SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';

  NUM_ROWS LAST_ANALYZED
---------- ---------------
       700 03-SEP-22

--11.再插入两个分区数据
INSERT INTO TEST3
SELECT ROWNUM,TO_DATE('20210331','YYYYMMDD') FROM DBA_OBJECTS WHERE ROWNUM <= 100;
INSERT INTO TEST3
SELECT ROWNUM,TO_DATE('20210401','YYYYMMDD') FROM DBA_OBJECTS WHERE ROWNUM <= 100;
COMMIT ;

--查看分区统计信息
set linesize 200
col PARTITION_NAME for a30
SELECT P.PARTITION_NAME, P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TAB_PARTITIONS P
 WHERE TABLE_NAME = 'TEST3';

PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ---------- ---------------
P_20180101                              0 03-SEP-22
SYS_P903                              100 03-SEP-22
SYS_P904                              100 03-SEP-22
SYS_P905                              100 03-SEP-22
SYS_P906                              100 03-SEP-22
SYS_P907                              100 03-SEP-22
SYS_P908                              100 03-SEP-22
SYS_P909                              100 03-SEP-22
SYS_P910
SYS_P911

10 rows selected.

--查看全局统计信息
SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';

 NUM_ROWS LAST_ANALYZED
---------- ---------------
       700 03-SEP-22

--11.通过测试可以通过指定granularity => 'APPROX_GLOBAL AND PARTITION',机制是仅将指定分区的统计信息增加到全局信息中。
exec dbms_stats.gather_table_stats(user,'TEST3',partname => 'SYS_P910',granularity => 'APPROX_GLOBAL AND PARTITION');

--可以看到本次全局统计信息仅将SYS_P890的100条增加到全局统计信息中,而不是全部收集
set linesize 200
col PARTITION_NAME for a30
SELECT P.PARTITION_NAME, P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TAB_PARTITIONS P
 WHERE TABLE_NAME = 'TEST3';

PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ---------- ---------------
P_20180101                              0 03-SEP-22
SYS_P903                              100 03-SEP-22
SYS_P904                              100 03-SEP-22
SYS_P905                              100 03-SEP-22
SYS_P906                              100 03-SEP-22
SYS_P907                              100 03-SEP-22
SYS_P908                              100 03-SEP-22
SYS_P909                              100 03-SEP-22
SYS_P910                              100 03-SEP-22
SYS_P911

10 rows selected.

SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';

  NUM_ROWS LAST_ANALYZED
---------- ---------------
       800 03-SEP-22

--使用granularity => 'APPROX_GLOBAL AND PARTITION' 收集另外一个分区的统计信息	   
exec dbms_stats.gather_table_stats(user,'TEST3',partname => 'SYS_P911',granularity => 'APPROX_GLOBAL AND PARTITION');

--查看分区统计信息
set linesize 200
col PARTITION_NAME for a30
SELECT P.PARTITION_NAME, P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TAB_PARTITIONS P
 WHERE TABLE_NAME = 'TEST3';
 
PARTITION_NAME                   NUM_ROWS LAST_ANALYZED
------------------------------ ---------- ---------------
P_20180101                              0 03-SEP-22
SYS_P903                              100 03-SEP-22
SYS_P904                              100 03-SEP-22
SYS_P905                              100 03-SEP-22
SYS_P906                              100 03-SEP-22
SYS_P907                              100 03-SEP-22
SYS_P908                              100 03-SEP-22
SYS_P909                              100 03-SEP-22
SYS_P910                              100 03-SEP-22
SYS_P911                              100 03-SEP-22

10 rows selected.

--查看全局统计信息
SELECT P.NUM_ROWS, P.LAST_ANALYZED
  FROM DBA_TABLES P
 WHERE TABLE_NAME = 'TEST3';
 
  NUM_ROWS LAST_ANALYZED
---------- ---------------
       900 03-SEP-22

--12.再测试下跨分区的准确性,答案是准确的
SET AUTOTRACE TRACEONLY
SELECT * FROM TEST3 WHERE PARDATE = TO_DATE('20210331', 'YYYYMMDD');
----------------------------------------------------------------------------
| Id  | Operation              | Name  | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |       |   100 |  1100 |     3   (0)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE SINGLE|       |   100 |  1100 |     3   (0)| 00:00:01 |  1186 |  1186 |
|*  2 |   TABLE ACCESS FULL    | TEST3 |   100 |  1100 |     3   (0)| 00:00:01 |  1186 |  1186 |
------------------------------------------------------------------------------------------------
 
SQL> SELECT * FROM TEST3 WHERE PARDATE = TO_DATE('20210401', 'YYYYMMDD');
------------------------------------------------------------------------------------------------
| Id  | Operation              | Name  | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |       |   100 |  1100 |     3   (0)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE SINGLE|       |   100 |  1100 |     3   (0)| 00:00:01 |  1187 |  1187 |
|*  2 |   TABLE ACCESS FULL    | TEST3 |   100 |  1100 |     3   (0)| 00:00:01 |  1187 |  1187 |
------------------------------------------------------------------------------------------------
 
SQL> SELECT * FROM TEST3 WHERE PARDATE IN (TO_DATE('20210331', 'YYYYMMDD'),TO_DATE('20210401', 'YYYYMMDD'));
------------------------------------------------------------------------------------------------
| Id  | Operation              | Name  | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |       |   200 |  2200 |     4   (0)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE INLIST|       |   200 |  2200 |     4   (0)| 00:00:01 |KEY(I) |KEY(I) |
|*  2 |   TABLE ACCESS FULL    | TEST3 |   200 |  2200 |     4   (0)| 00:00:01 |KEY(I) |KEY(I) |
------------------------------------------------------------------------------------------------

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值