Incremental statistics for partitioned tables in 11g by wwf from ebay COC

  • 2,619 views
Uploaded on

wwf's doc about 11g new feature

wwf's doc about 11g new feature

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,619
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
55
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. 1, what oracle document tells us?For partitioned tables, when we collect statistics, even when only one partition changed, such asadd a new partition or load some data to a partition,we have to scan all partitions to compute global statistics, this is much resource intensiveoperation.In 11G, oracle introduced “incremental” statistics gather option for partitioned table. When apartitioned table is set to “incremental” attribute, it will storea synopsis on sysaux tablespace for global level statistics(it will only consume very littlespace), then, it will only scan one partition but will updatethe global statistics, which will save many resource.2, my test:2.0: My Test Environments:Oracle version is: 11.1.0.6,OS: Solaris2.1 create test table:Let us create 2 tables test_inc(enable incremental statistics) and test_inc_bak(disableincremental statistics) with same structure:SQL> create table test_inc test_inc(a number, b date, c varchar2(30), d varchar2(100), evarchar2(100), partition_key number) 2 partition by range(partition_key) 3 ( 4 partition p00 values less than (1), 5 partition p01 values less than (2), 6 partition p02 values less than (3), 7 partition p03 values less than (4), 8 partition p04 values less than (5), 9 partition p05 values less than (6), 10 partition p06 values less than (7), 11 partition p07 values less than (8), 12 partition p08 values less than (9), 13 partition p09 values less than (10), 14 partition p10 values less than (11), 15 partition p11 values less than (12), 16 partition p12 values less than (13), 17 partition p13 values less than (14), 18 partition p14 values less than (15), 19 partition p15 values less than (16), 20 partition p16 values less than (17), 21 partition p17 values less than (18), 22 partition p18 values less than (19), 23 partition p19 values less than (20), 24 partition p20 values less than (21), 25 partition p21 values less than (22), 26 partition p22 values less than (23), 27 partition p23 values less than (24), 28 partition p24 values less than (25), 29 partition p25 values less than (26), 30 partition p26 values less than (27), 31 partition p27 values less than (28), 32 partition p28 values less than (29),
  • 2. 33 partition p29 values less than (30), 34 partition p30 values less than (31), 35 partition pmax values less than(maxvalue) 36 ) ;SQL> create table test_inc_bak test_inc_bak(a number, b date, c varchar2(30), dvarchar2(100), e varchar2(100), partition_key number) 2 partition by range(partition_key) 3 ( 4 partition p00 values less than (1), 5 partition p01 values less than (2), 6 partition p02 values less than (3), 7 partition p03 values less than (4), 8 partition p04 values less than (5), 9 partition p05 values less than (6), 10 partition p06 values less than (7), 11 partition p07 values less than (8), 12 partition p08 values less than (9), 13 partition p09 values less than (10), 14 partition p10 values less than (11), 15 partition p11 values less than (12), 16 partition p12 values less than (13), 17 partition p13 values less than (14), 18 partition p14 values less than (15), 19 partition p15 values less than (16), 20 partition p16 values less than (17), 21 partition p17 values less than (18), 22 partition p18 values less than (19), 23 partition p19 values less than (20), 24 partition p20 values less than (21), 25 partition p21 values less than (22), 26 partition p22 values less than (23), 27 partition p23 values less than (24), 28 partition p24 values less than (25), 29 partition p25 values less than (26), 30 partition p26 values less than (27), 31 partition p27 values less than (28), 32 partition p28 values less than (29), 33 partition p29 values less than (30), 34 partition p30 values less than (31), 35 partition pmax values less than(maxvalue) 36 );2.2 set incremental attribute for one table:Let enable “incremental” statistics gathering for test_inc:SQL> select DBMS_STATS.get_PREFS(incremental, wwf, test_inc) fromdual;DBMS_STATS.GET_PREFS(INCREMENTAL,WWF,TEST_INC)FALSESQL> execDBMS_STATS.SET_TABLE_PREFS(user,test_inc,INCREMENTAL,TRUE)PL/SQL procedure successfully completed.SQL> select DBMS_STATS.get_PREFS(incremental, wwf, test_inc) fromdual;DBMS_STATS.GET_PREFS(INCREMENTAL,WWF,TEST_INC)
  • 3. TRUEFor test_inc_bak, keep it disabled for “incremental” statistics gathering:SQL> select DBMS_STATS.get_PREFS(incremental, wwf, test_inc_bak) from dual;DBMS_STATS.GET_PREFS(INCREMENTAL,WWF,TEST_INC_BAK)---------------------------------------------------------------------------------------------------------------------------------FALSE2.3 The whole test process: populateThen, using the following sql to populate data for each partition(populate 300k records for eachpartition and change the value of partition key correspondingly correspondingly):insert into test_inc select rownum, sysdate+mod(rownum, 30),wangweifengwangweifeng||rownum,rpad(x, 50, x)||rownum, rpad(y, 50, z)||rownum, 0 from dual connect byrownum <= 300000 300000;insert into test_inc_bak select rownum, sysdate+mod(rownum, 30),wangweifengwangweifeng||rownum,rpad(x, 50, x)||rownum, rpad(y, 50, z)||rownum, 0 from dual connect byrownum <= 300000 300000;My test indicates that: the “incremental” attribute will make the statistics gathering process muchfaster!exec dbms_stats.gather_table_stats(user, test_inc)exec dbms_stats.gather_table_stats(user, test_inc_bak)2.4 test result and compareThe following table is the time spent for incremental/non-incremental tables statistics-gatheringprocess:partition Time elapsed for incremental table Time elapsed for non-incremental tablenumber test_inc(seconds) test_inc(seconds seconds) test_inc_bak (seconds) seconds) 1 4.37 4.36 2 4.47 8.66 3 5.09 13.2 4 5.38 19.48 5 5.47 24.06 6 5.76 29.39 7 6.13 34.03 8 6.62 38.97 9 7.28 46.24 10 7.32 50.75 11 7.53 56.83 12 7.86 62.25 13 8.62 67.06 14 8.89 72.73 15 9.48 78.93 16 10.01 83.66 17 10.77 87.44
  • 4. 18 11.22 93.74 19 10.72 100.85 20 11.48 105.54 21 11.01 112.08 22 11.06 116.53 23 10.68 123.57 24 12.58 126.58 25 8.01 135.41 26 12.38 137.95 27 13.09 144.33 28 14.67 149.75 29 13.55 153.94 30 14.27 160.50 31 14.15 165.50Use the above data, let’s plot picture: let’We can see, for non-incremental partitioned table, the time elapsed for non-incremental (theyellow line) is linear with the partition number.While for the incremental partitioned table, the time elapsed (the red line) is nearly a flat line:The red line represent time elapsed for incremental partitioned tableThe yellow line time elapsed for non-incremental partitioned table
  • 5. 2.5: let’s see from another perspective: what last_analyzed column can tell let’us?SQL> exec dbms_stats.gather_table_stats(user, test_inc test_inc)PL/SQL procedure successfully completed.Elapsed: 00:00:04.37SQL> select partition_name, blocks, num_rows, last_analyzed fromuser_tab_partitions where table_name = TEST_INC and num_rows > 0;PARTITION_NAME BLOCKS NUM_ROWS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 6796 300000 2009-09-09 00:49:51SQL> select table_name, blocks, num_rows, last_analyzed fromuser_tables where table_name = TEST_INC;TABLE_NAME BLOCKS NUM_ROWS LAST_ANALYZED------------------------------ ---------- ---------- -------------------TEST_INC 6796 300000 2009-09-09 00:49:51Insert 300k records for empty partition p2:SQL> exec dbms_stats.gather_table_stats(user, test_inc)PL/SQL procedure successfully completed.Elapsed: 00:00:04.47SQL> select partition_name, blocks, num_rows, last_analyzed fromuser_tab_partitions where table_name = TEST_INC and num_rows > 0;PARTITION_NAME BLOCKS NUM_ROWS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 6796 300000 2009-09-09 00:49:51P01 6796 300000 2009-09-09 00:52:27SQL> select table_name, blocks, num_rows, last_analyzed from user_tables wheretable_name = TEST_INC;TABLE_NAME BLOCKS NUM_ROWS LAST_ANALYZED------------------------------ ---------- ---------- -------------------TEST_INC 13592 600000 2009-09-09 00:52:29Insert 300k records for empty partition p3:SQL> exec dbms_stats.gather_table_stats(user, test_inc)PL/SQL procedure successfully completed.Elapsed: 00:00:05.09SQL> select partition_name, blocks, num_rows, last_analyzed fromuser_tab_partitions where table_name = TEST_INC and num_rows > 0;PARTITION_NAME BLOCKS NUM_ROWS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 6796 300000 2009-09-09 00:49:51P01 6796 300000 2009-09-09 00:52:27P02 6796 300000 2009-09-09 00:55:39
  • 6. SQL> select table_name, blocks, num_rows, last_analyzed from user_tables wheretable_name = TEST_INC;TABLE_NAME BLOCKS NUM_ROWS LAST_ANALYZED------------------------------ ---------- ---------- -------------------TEST_INC 20388 900000 2009-09-09 00:55:40Insert 300k records for empty partition p4:SQL> exec dbms_stats.gather_table_stats(user, test_inc)PL/SQL procedure successfully completed.Elapsed: 00:00:05.38SQL> select partition_name, blocks, num_rows, last_analyzed fromuser_tab_partitions where table_name = TEST_INC 2 and num_rows > 0;PARTITION_NAME BLOCKS NUM_ROWS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 6796 300000 2009-09-09 00:49:51P01 6796 300000 2009-09-09 00:52:27P02 6796 300000 2009-09-09 00:55:39P03 6796 300000 2009-09-09 01:00:23SQL> select table_name, blocks, num_rows, last_analyzed fromuser_tables where table_name = TEST_INC;TABLE_NAME BLOCKS NUM_ROWS LAST_ANALYZED------------------------------ ---------- ---------- -------------------TEST_INC 27184 1200000 2009-09-09 01:00:24We can see that: the last_analyzed column won’t change after each analyze. won’This can tell us that: the unchanged analyzed partition is skipped when enable incrementalstatistics gathering.But, let’s see the last_analyzed column for non-incremental partitions table: let’The last_analyze column changes when every analyze: this is the last time I analyzed thenon-incremental table test_inc_bak(I started my test from 09/09/2009):SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = TEST_INC_BAK TEST_INC_BAK;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 300000 6796 2009-09-11 01:07:43P01 300000 6796 2009-09-11 01:07:46P02 300000 6796 2009-09-11 01:07:49P03 300000 6796 2009-09-11 01:07:52P04 300000 6796 2009-09-11 01:07:54P05 300000 6796 2009-09-11 01:07:57P06 300000 6796 2009-09-11 01:08:00P07 300000 6796 2009-09-11 01:08:03P08 300000 6796 2009-09-11 01:08:06P09 300000 6796 2009-09-11 01:08:09P10 300000 6796 2009-09-11 01:08:13P11 300000 6796 2009-09-11 01:08:16P12 300000 6796 2009-09-11 01:08:19P13 300000 6796 2009-09-11 01:08:22P14 300000 6796 2009-09-11 01:08:24P15 300000 6796 2009-09-11 01:08:27
  • 7. P16 300000 6796 2009-09-11 01:08:30P17 300000 6796 2009-09-11 01:08:33P18 300000 6796 2009-09-11 01:08:36P19 300000 6796 2009-09-11 01:08:39P20 300000 6796 2009-09-11 01:08:42P21 300000 6796 2009-09-11 01:08:45P22 300000 6796 2009-09-11 01:08:48P23 300000 6796 2009-09-11 01:08:51P24 300000 6796 2009-09-11 01:08:54P25 300000 6796 2009-09-11 01:08:57P26 300000 6796 2009-09-11 01:09:00P27 300000 6796 2009-09-11 01:09:03P28 300000 6796 2009-09-11 01:09:06P29 300000 6796 2009-09-11 01:09:09P30 300000 6796 2009-09-11 01:09:11PMAX 0 0 2009-09-11 01:09:11While the following is what analyze looks like when I finish the analyze on incrementaltable test_inc_bak:SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = TEST_INCTEST_INC;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 300000 6796 2009-09-09 00:49:51P01 300000 6796 2009-09-09 00:52:27P02 300000 6796 2009-09-09 00:55:39P03 300000 6796 2009-09-09 01:00:23P04 300000 6796 2009-09-09 01:04:59P05 300000 6796 2009-09-09 01:09:37P06 300000 6796 2009-09-09 01:14:06P07 300000 6796 2009-09-09 01:17:33P08 300000 6796 2009-09-09 01:22:14P09 300000 6796 2009-09-09 01:28:15P10 300000 6796 2009-09-09 01:33:29P11 300000 6796 2009-09-09 01:36:36P12 300000 6796 2009-09-09 01:42:39P13 300000 6796 2009-09-09 01:46:54P14 300000 6796 2009-09-09 01:55:36P15 300000 6796 2009-09-09 02:04:55P16 300000 6796 2009-09-09 02:20:34P17 300000 6796 2009-09-09 03:05:48P18 300000 6796 2009-09-09 03:38:40P19 300000 6796 2009-09-09 04:10:07P20 300000 6796 2009-09-09 04:14:57P21 300000 6796 2009-09-09 04:46:03P22 300000 6796 2009-09-09 04:57:09P23 300000 6796 2009-09-09 05:28:45P24 300000 6796 2009-09-11 22:03:14P25 300000 6796 2009-09-11 00:31:14P26 300000 6796 2009-09-11 00:37:14P27 300000 6796 2009-09-11 00:44:13P28 300000 6796 2009-09-11 00:52:49P29 300000 6796 2009-09-11 01:00:16P30 300000 6796 2009-09-11 01:06:34PMAX 0 0 2009-09-11 01:06:342.6 The drawback or bugs of incremental statistics:2.6.1: It is only sensitive for newly load data partition:
  • 8. Per my test, it seems that, “incremental statistics” is only sensitive for a new partition which iscompletely newly loaded data. It can be aware of the following situations: a. delete/insert some data to a partition that has already been analyzed b. truncate one/more partitionsPlease see my test: The table currently has 1.8 million records, each partition contain 0.3 million records:SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = TEST_INC and num_rows > 0;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 300000 6796 2009-09-12 01:41:56P01 300000 6796 2009-09-12 01:45:07P02 300000 6796 2009-09-12 01:47:11P03 300000 6796 2009-09-12 01:50:11P04 300000 6796 2009-09-12 01:51:41P05 300000 6796 2009-09-12 01:52:48Delete 100k records for partition p05:SQL> delete from test_inc partition(p05) where rownum <= 100000;100000 rows deleted.Truncate partition p04:SQL> alter table test_inc truncate partition p04 ;Table truncated.Insert 100k records to partition p01:SQL> insert into test_inc select rownum, sysdate+mod(rownum, 30),wangweifengwangweifeng||rownum, 2 rpad(x, 50, x)||rownum, rpad(y, 50, z)||rownum, 1 from dualconnect by rownum <= 300000;300000 rows created.But, let us analyze it:SQL> exec dbms_stats.gather_table_stats(user, test_inc);PL/SQL procedure successfully completed.SQL> select table_name, num_rows, blocks, last_analyzed fromuser_tables where table_name = TEST_INC;TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------TEST_INC 1800000 41361 2009-09-12 01:57:21SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = TEST_INC and num_rows > 0;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 300000 6796 2009-09-12 01:41:56P01 300000 6796 2009-09-12 01:45:07P02 300000 6796 2009-09-12 01:47:11
  • 9. P03 300000 6796 2009-09-12 01:50:11P04 300000 6796 2009-09-12 01:51:41P05 300000 6796 2009-09-12 01:52:486 rows selected.SQL> select count(*) from test_inc partition(p05); COUNT(*)---------- 200000SQL> select count(*) from test_inc partition(p06); COUNT(*)---------- 0SQL> select count(*) from test_inc partition(p01); COUNT(*)---------- 600000We can see, the statistics does not change at all!Then, will it triggered by populating data into a newly loaded partition?It won’t! Let me insert data to an empty partition p06: won’SQL> insert into test_inc select rownum, sysdate+mod(rownum, 30),wangweifengwangweifeng||rownum, 2 rpad(x, 50, x)||rownum, rpad(y, 50, z)||rownum, 6 fromdual connect by rownum <= 300000;300000 rows created.SQL> exec dbms_stats.gather_table_stats(user, test_inc);PL/SQL procedure successfully completed.Elapsed: 00:00:06.61SQL> select table_name, num_rows, blocks, last_analyzed fromuser_tables where table_name = TEST_INC;TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------TEST_INC 2100000 48157 2009-09-12 02:01:36SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = TEST_INC and num_rows > 0;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 300000 6796 2009-09-12 01:41:56P01 300000 6796 2009-09-12 01:45:07P02 300000 6796 2009-09-12 01:47:11P03 300000 6796 2009-09-12 01:50:11P04 300000 6796 2009-09-12 01:51:41P05 300000 6796 2009-09-12 01:52:48
  • 10. P06 300000 6796 2009-09-12 02:01:337 rows selected.How about I truncate all tables?Let me initialize the table and populate 2.1 million records for 7 partitions:SQL> select table_name, num_rows, blocks, last_analyzed fromuser_tables where table_name = TEST_INC;TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------TEST_INC 2100000 47572 2009-09-12 04:05:18SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = TEST_INC and num_rows > 0;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 300000 6796 2009-09-12 03:53:58P01 300000 6796 2009-09-12 03:54:42P02 300000 6796 2009-09-12 03:55:24P03 300000 6796 2009-09-12 04:01:54P04 300000 6796 2009-09-12 04:03:33P05 300000 6796 2009-09-12 04:04:26P06 300000 6796 2009-09-12 04:05:167 rows selected.SQL> truncate table test_inc;Table truncated.Elapsed: 00:00:02.24SQL> exec dbms_stats.gather_table_stats(user, test_inc);PL/SQL procedure successfully completed.Elapsed: 00:00:00.61SQL> select table_name, num_rows, blocks, last_analyzed fromuser_tables where table_name = TEST_INC;TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------TEST_INC 0 0 2009-09-12 04:09:43SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = TEST_INC and num_rows > 0;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 300000 6796 2009-09-12 03:53:58P01 300000 6796 2009-09-12 03:54:42P02 300000 6796 2009-09-12 03:55:24P03 300000 6796 2009-09-12 04:01:54P04 300000 6796 2009-09-12 04:03:33P05 300000 6796 2009-09-12 04:04:26P06 300000 6796 2009-09-12 04:05:167 rows selected.
  • 11. We can see: the statistics for table level is got updated, but, it is not got updated forpartition level!I think, it should be a bug! Anyway, I will file TAR for Oracle for clarify.How to fix it temporarily? Set it back to “no-incremental”, then analyze again: no-incremental”SQL> execDBMS_STATS.SET_TABLE_PREFS(user,test_inc,INCREMENTAL,FALSE FALSE FALSE);PL/SQL procedure successfully completed.SQL> select DBMS_STATS.get_PREFS(incremental, wwf, test_inc) fromdual;DBMS_STATS.GET_PREFS(INCREMENTAL,WWF,TEST_INC)-----------------------------------------------------------------------FALSESQL> exec dbms_stats.gather_table_stats(user, test_inc);PL/SQL procedure successfully completed.SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = TEST_INC and num_rows > 0;no rows selectedSQL> select table_name, num_rows, blocks, last_analyzed fromuser_tables where table_name = TEST_INC;TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------TEST_INC 0 0 2009-09-12 04:18:34SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = TEST_INC;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 0 0 2009-09-12 04:18:34P01 0 0 2009-09-12 04:18:34P02 0 0 2009-09-12 04:18:34P03 0 0 2009-09-12 04:18:34P04 0 0 2009-09-12 04:18:34P05 0 0 2009-09-12 04:18:34P06 0 0 2009-09-12 04:18:34P07 0 0 2009-09-12 04:18:342.6.2 For subpartition table, it is totally wrong:SQL> CREATE TABLE composite_rng_list ( 2 cust_id NUMBER(10), 3 cust_name VARCHAR2(25), 4 cust_state VARCHAR2(2), 5 time_id DATE) 6 PARTITION BY RANGE(time_id) 7 SUBPARTITION BY LIST (cust_state) 8 SUBPARTITION TEMPLATE( 9 SUBPARTITION west VALUES (OR, WA),
  • 12. 10 SUBPARTITION east VALUES (NY, CT), 11 SUBPARTITION cent VALUES (OK, TX)) ( 12 PARTITION per1 VALUES LESS THAN (TO_DATE(01/01/2008,DD/MM/YYYY)), 13 PARTITION per2 VALUES LESS THAN (TO_DATE(01/01/2010,DD/MM/YYYY)), 14 PARTITION per3 VALUES LESS THAN (TO_DATE(01/01/2012,DD/MM/YYYY)), 15 PARTITION future VALUES LESS THAN(MAXVALUE));Table created.SQL> exec dbms_stats.set_table_prefs(wwf, composite_rng_list,incremental, true)PL/SQL procedure successfully completed.Elapsed: 00:00:00.01SQL> select dbms_stats.get_prefs(incremental, wwf,composite_rng_list) from dual;DBMS_STATS.GET_PREFS(INCREMENTAL,WWF,COMPOSITE_RNG_LIST)---------------------------------------------------------------------TRUESQL> insert into composite_rng_list select rownum, customer||rownum, OR,to_date(2007-01-01, yyyy-mm-dd) from dual connect by rownum <= 100000;100000 rows created.SQL> commit;Commit complete.SQL> select table_name, num_rows, blocks, last_analyzed from user_tables wheretable_name = COMPOSITE_RNG_LIST;TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------COMPOSITE_RNG_LIST 100000 496 2009-09-14 18:17:58Elapsed: 00:00:00.01SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = COMPOSITE_RNG_LIST and rownum > 0;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED---------------- ---------- ---------- -------------------PER1 100000 496 2009-09-14 18:17:57Elapsed: 00:00:00.00SQL> select partition_name, SUBPARTITION_NAME, num_rows, blocks, last_analyzedfrom user_tab_subpartitions where table_name = COMPOSITE_RNG_LIST and rownum> 0;PARTITION_NAME SUBPARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED---------------- ---------------- ---------- ---------- -------------------PER1 PER1_WEST 100000 496 2009-09-14 18:17:55Then, insert 100000 more rows and analyze again, we can see that, thestatistics at partition level and table level were not changed at all:SQL> insert into composite_rng_list select rownum, customer||rownum, WA,to_date(2007-01-01, yyyy-mm-dd) from dual connect by rownum <= 100000;
  • 13. 100000 rows created.SQL> commit;Commit complete.SQL> exec dbms_stats.gather_table_stats(user, COMPOSITE_RNG_LIST,granularity=>ALL)PL/SQL procedure successfully completed.SQL> select table_name, num_rows, blocks, last_analyzed from user_tables wheretable_name = COMPOSITE_RNG_LIST;TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------COMPOSITE_RNG_LIST 100000 1000 2009-09-14 18:24:12SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = COMPOSITE_RNG_LIST and num_rows > 0;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------PER1 100000 496 2009-09-14 18:17:57SQL> select partition_name, SUBPARTITION_NAME, num_rows, blocks, last_analyzedfrom user_tab_subpartitions where table_name = COMPOSITE_RNG_LIST andnum_rows > 0;PARTITION_NAME SUBPARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED--------------- -------------- ---------- ---------- -------------------PER1 PER1_WEST 200000 1000 2009-09-14 18:24:11Then, insert 100000 more rows and analyze again, we can see that, thestatistics at partition level and table level were not changed at all:SQL> insert into composite_rng_list select rownum, customer||rownum,NY, to_date(2007-01-01, yyyy-mm-dd) from dual connect by rownum <=100000;100000 rows created.SQL> commit;Commit complete.SQL> exec dbms_stats.gather_table_stats(user, COMPOSITE_RNG_LIST,granularity=>ALL)PL/SQL procedure successfully completed.SQL> select table_name, num_rows, blocks, last_analyzed from user_tables wheretable_name = COMPOSITE_RNG_LIST;TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------------------------ ---------- ---------- -------------------COMPOSITE_RNG_LIST 100000 1496 2009-09-14 18:26:33SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = COMPOSITE_RNG_LIST and num_rows > 0;PARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED----------------- ---------- ---------- -------------------PER1 100000 496 2009-09-14 18:17:57
  • 14. SQL> select partition_name, SUBPARTITION_NAME, num_rows, blocks, last_analyzedfrom user_tab_subpartitions where table_name = COMPOSITE_RNG_LIST andnum_rows > 0;PARTITION_NAME SUBPARTITION_NAME NUM_ROWS BLOCKS LAST_ANALYZED------------ ----------------- ---------- ---------- -------------------PER1 PER1_WEST 200000 1000 2009-09-14 18:26:32PER1 PER1_EAST 100000 496 2009-09-14 18:26:32Also, I do more test on subpartitione table. It can not displayaccurate statistics on partition level and table level.2.6.3 There is no incremental statistics for partitioned indexes on partitioned tables:On the partitioned table in 2.1, we create a local partitioned index:SQL> create index ind_test_inc on test_inc(a) local;Index created.Insert 300k rows, then analyze:SQL> select partition_name, num_rows, DISTINCT_KEYS, clustering_factor,last_analyzed from user_ind_partitions where index_name = IND_TEST_INC andnum_rows > 0;PARTITION_NAME NUM_ROWS DISTINCT_KEYS CLUSTERING_FACTOR LAST_ANALYZED--------------- --------- ------------- ----------------- ------------------P00 300000 300000 6763 2009-09-14 19:43:01Insert 300k rows, then analyze:SQL> select partition_name, num_rows, DISTINCT_KEYS, clustering_factor,last_analyzed from user_ind_partitions where index_name = IND_TEST_INC andnum_rows > 0;PARTITION_NAME NUM_ROWS DISTINCT_KEYS CLUSTERING LAST_ANALYZED FACTOR------------- ---------- ------------- ----------------- --------------P00 300000 300000 6763 2009-09-14 19:54:35P01 300000 300000 6763 2009-09-14 19:54:35Insert 300k rows, then, analyze:SQL> select num_rows, DISTINCT_KEYS, clustering_factor, last_analyzed fromuser_indexes where index_name = IND_TEST_INC; NUM_ROWS DISTINCT_KEYS CLUSTERING_FACTOR LAST_ANALYZED---------- ------------- ----------------- ------------------- 900000 302976 20289 2009-09-14 20:00:50SQL> select partition_name, num_rows, DISTINCT_KEYS, clustering_factor,last_analyzed from user_ind_partitions where index_name = IND_TEST_INC andnum_rows > 0;PARTITION_NAME NUM_ROWS DISTINCT_KEYS CLUSTERING_FACTOR LAST_ANALYZED--------------- ---------- ------------- ----------------- -------------------P00 300000 300000 6763 2009-09-14 20:00:50P01 300000 300000 6763 2009-09-14 20:00:50P02 300000 300000 6763 2009-09-14 20:00:50It seems that there is no way to set index “ind_test_inc” as incremental: ind_test_inc”SQL> select dbms_stats.get_prefs(incremental, wwf, test_inc) from dual;DBMS_STATS.GET_PREFS(INCREMENTAL,WWF,TEST_INC)
  • 15. --------------------------------------------TRUEElapsed: 00:00:00.01SQL> select dbms_stats.get_prefs(incremental, wwf, ind_test_inc from ind_test_inc)dual;DBMS_STATS.GET_PREFS(INCREMENTAL,WWF,IND_TEST_INC)-----------------------------------------------FALSEElapsed: 00:00:00.01SQL> exec dbms_stats.set_table_prefs(wwf, ind_test_inc incremental, ind_test_inc,true)BEGIN dbms_stats.set_table_prefs(wwf, ind_test_inc, incremental, true);END;*ERROR at line 1:ORA-20000: TABLE "WWF"."IND_TEST_INC" does not exist or insufficient privilegesORA-06512: at "SYS.DBMS_STATS", line 2091ORA-06512: at "SYS.DBMS_STATS", line 24110ORA-06512: at line 1I will do tests on 11G Release 2 once it is available for download on Solaris version.But, from the document of 11G Release 2, which has been already available, there is stillno such function in such as set_index_prefs provided.3. Under the hood3.1 Where the synopsis exists?As it is said in part 1, it is in sysaux tablespace:SQL> select OCCUPANT_NAME, OCCUPANT_DESC, SPACE_USAGE_KBYTES/power(1024,2) fromv$sysaux_occupants order by 2;OCCUPANT_NAME OCCUPANT_DESC SPACE_USAGE_KBYTES/POWER(1024,2)--------------------- ---------------------------------------------------- --------------------------------AO Analytical Workspace ObjectTable .001342773AUTO_TASK Automated MaintenanceTasks .000305176EM_MONITORING_USER Enterprise Manager MonitoringUser .001647949LOGMNR LogMiner .007385254LOGSTDBY LogicalStandby .000976563XSOQHIST OLAP API HistoryTables .001342773STREAMS OracleStreams .000976563TSM Oracle Transparent Session MigrationUser .000244141PL/SCOPE PL/SQL IdentifierCollection .000366211SQL_MANAGEMENT_BASE SQL Management BaseSchema .001647949
  • 16. SM/ADVISOR Server Manageability - AdvisorFramework .016052246SM/AWR Server Manageability - Automatic WorkloadRepository .125610352SM/OPTSTAT Server Manageability - Optimizer StatisticsHistory .115722656SM/OTHER Server Manageability - OtherComponents .00567627SMON_SCN_TIME Transaction Layer - SCN to TIMEmapping .003173828JOB_SCHEDULER Unified JobScheduler .00061035229 rows selected.The blue line represents the space occupied by the synopsis for global level statistics.Usually, it will only consume very little space.Using sql_trace, found that the attribute for incremental for a table is stored in tableSYS.OPTSTAT_USER_PREF$:SQL> select a.obj#, name, pname, valchar from SYS.OPTSTAT_USER_PREFS$ a, obj$ bwhere a.obj# = b.obj#; OBJ# NAME PNAME VALCHAR---------- ------------------------------ -------------------- ---------------- 15307 TEST_INC INCREMENTAL TRUEIn fact, for a partitioned table, the global level “NDV” (Number of Distinct Value) of NDV”columns is the most challengeable. All other statistics can be speculated from partitionlevel, such as num_rows, blocks, avg_row_len. So, I think, this is what Oracle 11G Release2 enhances.4. My conclusion:I think, incremental statistics gathering for partitioned tables is a very useful new featureintroduced by ORACLE 11G if all the bugs can be resolved.It will consume much less resource especially for large partitioned/subpartitioned tablesand shorten our statistics gathering process. I believe it willnot only help us for our normal analyze CR, but also it will help us under situations undertough situations (such as TCB) caused by inaccurate statistics,as at such situations, time is so precious for us.Anyway, I will track this feature.Thanks!