16
1, 1, 1, 1, what what what what oracle oracle oracle oracle document document document document tells tells tells tells us? us? us? us? For partitioned tables, when we collect statistics, even when only one partition changed, such as add a new partition or load some data to a partition, we have to scan all partitions to compute global statistics, this is much resource intensive operation. In 11G, oracle introduced “incremental” statistics gather option for partitioned table. When a partitioned table is set to “incremental” attribute, it will store a synopsis synopsis synopsis synopsis on sysaux tablespace for global level statistics(it will only consume very little space), then, it will only scan one partition but will update the global statistics, which will save many resource. 2, 2, 2, 2, my my my my test: test: test: test: 2.0: 2.0: 2.0: 2.0: My My My My Test Test Test Test Environments: Environments: Environments: Environments: Oracle Oracle Oracle Oracle version version version version is: is: is: is: 11.1.0.6, 11.1.0.6, 11.1.0.6, 11.1.0.6, OS: OS: OS: OS: Solaris Solaris Solaris Solaris 2.1 2.1 2.1 2.1 create create create create test test test test table: table: table: table: Let us create 2 tables test_inc(enable incremental statistics) and test_inc_bak(disable incremental statistics) with same structure: SQL> create table test_inc test_inc test_inc test_inc(a number, b date, c varchar2(30), d varchar2(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),

Incrementalstatistics for partitioned tables in11g

Embed Size (px)

DESCRIPTION

Incrementalstatistics for partitioned tables in11g

Citation preview

  • 1,1,1,1, whatwhatwhatwhat oracleoracleoracleoracle documentdocumentdocumentdocument tellstellstellstells us?us?us?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 synopsissynopsissynopsissynopsis 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,2,2,2, mymymymy test:test:test:test:

    2.0:2.0:2.0:2.0: MyMyMyMy TestTestTestTest Environments:Environments:Environments:Environments:

    OracleOracleOracleOracle versionversionversionversion is:is:is:is: 11.1.0.6,11.1.0.6,11.1.0.6,11.1.0.6,OS:OS:OS:OS: SolarisSolarisSolarisSolaris

    2.12.12.12.1 createcreatecreatecreate testtesttesttest table:table:table:table:Let us create 2 tables test_inc(enable incremental statistics) and test_inc_bak(disableincremental statistics) with same structure:SQL> create table test_inctest_inctest_inctest_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),

  • 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_baktest_inc_baktest_inc_baktest_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.22.22.22.2 setsetsetset incrementalincrementalincrementalincremental attributeattributeattributeattribute forforforfor oneoneoneone table:table:table: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')

    FALSEFALSEFALSEFALSE

    SQL> 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')

  • TRUETRUETRUETRUE

    For 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')---------------------------------------------------------------------------------------------------------------------------------FALSEFALSEFALSEFALSE

    2.32.32.32.3 TheTheTheThe wholewholewholewhole testtesttesttest process:process:process:process:Then, using the following sql to populate data for each partition(populatepopulatepopulatepopulate 300k300k300k300k recordsrecordsrecordsrecords forforforfor eacheacheacheachpartitionpartitionpartitionpartition andandandand changechangechangechange thethethethe valuevaluevaluevalue ofofofof partitionpartitionpartitionpartition keykeykeykey correspondinglycorrespondinglycorrespondinglycorrespondingly):insert into test_inc select rownum, sysdate+mod(rownum, 30),'wangweifengwangweifeng'||rownum,rpad('x', 50, 'x')||rownum, rpad('y', 50, 'z')||rownum, 0000 from dual connect byrownum

  • 18 11.22 93.7419 10.72 100.8520 11.48 105.5421 11.01 112.0822 11.06 116.5323 10.68 123.5724 12.58 126.5825 8.01 135.4126 12.38 137.9527 13.09 144.3328 14.67 149.7529 13.55 153.9430 14.27 160.5031 14.15 165.50

    UseUseUseUse thethethethe aboveaboveaboveabove data,data,data,data, letletletletssss plotplotplotplot picture:picture:picture:picture: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:

    TheTheTheThe redredredred linelinelineline representrepresentrepresentrepresent timetimetimetime elapsedelapsedelapsedelapsed forforforfor incrementalincrementalincrementalincremental partitionedpartitionedpartitionedpartitioned tabletabletabletableTheTheTheThe yellowyellowyellowyellow linelinelineline timetimetimetime elapsedelapsedelapsedelapsed forforforfor non-incrementalnon-incrementalnon-incrementalnon-incremental partitionedpartitionedpartitionedpartitioned tabletabletabletable

  • 2.5:2.5:2.5:2.5: letletletletssss seeseeseesee fromfromfromfrom anotheranotheranotheranother perspective:perspective:perspective:perspective: whatwhatwhatwhat last_analyzedlast_analyzedlast_analyzedlast_analyzed columncolumncolumncolumn cancancancan telltelltelltellus?us?us?us?

    SQL> exec dbms_stats.gather_table_stats(user, 'test_inc''test_inc''test_inc''test_inc')

    PL/SQL procedure successfully completed.

    Elapsed: 00:00:04.37

    SQL> select partition_name, blocks, num_rows, last_analyzed fromuser_tab_partitions where table_name = 'TEST_INC' and num_rowsnum_rowsnum_rowsnum_rows >>>> 0;0;0;0;

    PARTITION_NAME BLOCKS NUM_ROWS LAST_ANALYZED------------------------------ ---------- ---------- -------------------P00 6796 300000 2009-09-09 00:49:5100:49:5100:49:5100:49:51

    SQL> 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 300000300000300000300000 2009-09-09 00:49:51

    InsertInsertInsertInsert 300k300k300k300k recordsrecordsrecordsrecords forforforfor emptyemptyemptyempty partitionpartitionpartitionpartition p2:p2:p2: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:5100:49:5100:49:5100:49:51P01 6796 300000 2009-09-09 00:52:2700:52:2700:52:2700:52:27

    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 13592 600000600000600000600000 2009-09-09 00:52:29

    InsertInsertInsertInsert 300k300k300k300k recordsrecordsrecordsrecords forforforfor emptyemptyemptyempty partitionpartitionpartitionpartition p3:p3:p3: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:5100:49:5100:49:5100:49:51P01 6796 300000 2009-09-09 00:52:2700:52:2700:52:2700:52:27P02 6796 300000 2009-09-09 00:55:3900:55:3900:55:3900:55:39

  • 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 900000900000900000900000 2009-09-09 00:55:40

    InsertInsertInsertInsert 300k300k300k300k recordsrecordsrecordsrecords forforforfor emptyemptyemptyempty partitionpartitionpartitionpartition p4:p4:p4:p4:SQL> exec dbms_stats.gather_table_stats(user, 'test_inc')

    PL/SQL procedure successfully completed.

    Elapsed: 00:00:05.38

    SQL> 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:5100:49:5100:49:5100:49:51P01 6796 300000 2009-09-09 00:52:2700:52:2700:52:2700:52:27P02 6796 300000 2009-09-09 00:55:3900:55:3900:55:3900:55:39P03 6796 300000 2009-09-09 01:00:23

    SQL> 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 1200000120000012000001200000 2009-09-09 01:00:24

    WeWeWeWe cancancancan seeseeseesee that:that:that:that: thethethethe last_analyzedlast_analyzedlast_analyzedlast_analyzed columncolumncolumncolumn wonwonwonwontttt changechangechangechange afterafterafterafter eacheacheacheach analyze.analyze.analyze.analyze.ThisThisThisThis cancancancan telltelltelltell usususus that:that:that:that: thethethethe unchangedunchangedunchangedunchanged analyzedanalyzedanalyzedanalyzed partitionpartitionpartitionpartition isisisis skippedskippedskippedskipped whenwhenwhenwhen enableenableenableenable incrementalincrementalincrementalincrementalstatisticsstatisticsstatisticsstatistics gathering.gathering.gathering.gathering.

    But,But,But,But, letletletletssss seeseeseesee thethethethe last_analyzedlast_analyzedlast_analyzedlast_analyzed columncolumncolumncolumn forforforfor non-incrementalnon-incrementalnon-incrementalnon-incremental partitionspartitionspartitionspartitions table:table:table:table:TheTheTheThe last_analyzelast_analyzelast_analyzelast_analyze columncolumncolumncolumn changeschangeschangeschanges whenwhenwhenwhen everyeveryeveryevery analyze:analyze:analyze:analyze: thisthisthisthis isisisis thethethethe lastlastlastlast timetimetimetime IIII analyzedanalyzedanalyzedanalyzed thethethethenon-incrementalnon-incrementalnon-incrementalnon-incremental tabletabletabletable test_inc_bak(Itest_inc_bak(Itest_inc_bak(Itest_inc_bak(I startedstartedstartedstarted mymymymy testtesttesttest fromfromfromfrom 09/09/2009):09/09/2009):09/09/2009):09/09/2009):SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = 'TEST_INC_BAK''TEST_INC_BAK''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

  • 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:11

    WhileWhileWhileWhile thethethethe followingfollowingfollowingfollowing isisisis whatwhatwhatwhat analyzeanalyzeanalyzeanalyze lookslookslookslooks likelikelikelike whenwhenwhenwhen IIII finishfinishfinishfinish thethethethe analyzeanalyzeanalyzeanalyze onononon incrementalincrementalincrementalincrementaltabletabletabletable test_inc_bak:test_inc_bak:test_inc_bak:test_inc_bak:SQL> select partition_name, num_rows, blocks, last_analyzed fromuser_tab_partitions where table_name = 'TEST_INC''TEST_INC''TEST_INC''TEST_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:34

    2.62.62.62.6 TheTheTheThe drawbackdrawbackdrawbackdrawback orororor bugsbugsbugsbugs ofofofof incrementalincrementalincrementalincremental statistics:statistics:statistics:statistics:

    2.6.1:2.6.1:2.6.1:2.6.1: ItItItIt isisisis onlyonlyonlyonly sensitivesensitivesensitivesensitive forforforfor newlynewlynewlynewly loadloadloadload datadatadatadata partition:partition:partition:partition:

  • 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 analyzedb. truncate one/more partitions

    Please 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:48

    Delete 100k records for partition p05:SQL> delete from test_inc partition(p05) where rownum 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, 1111 from dualconnect by rownum 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:21

    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:11

  • P03 300000 6796 2009-09-12 01:50:11P04P04P04P04 300000300000300000300000 6796679667966796 2009-09-122009-09-122009-09-122009-09-12 01:51:4101:51:4101:51:4101:51:41P05P05P05P05 300000300000300000300000 6796679667966796 2009-09-122009-09-122009-09-122009-09-12 01:52:4801:52:4801:52:4801:52:48

    6 rows selected.

    SQL> select count(*) from test_inc partition(p05);

    COUNT(*)----------

    200000

    SQL> select count(*) from test_inc partition(p06);

    COUNT(*)----------

    0

    SQL> select count(*) from test_inc partition(p01);

    COUNT(*)----------

    600000

    WeWeWeWe cancancancan see,see,see,see, thethethethe statisticsstatisticsstatisticsstatistics doesdoesdoesdoes notnotnotnot changechangechangechange atatatat all!all!all!all!Then,Then,Then,Then, willwillwillwill itititit triggeredtriggeredtriggeredtriggered bybybyby populatingpopulatingpopulatingpopulating datadatadatadata intointointointo aaaa newlynewlynewlynewly loadedloadedloadedloaded partition?partition?partition?partition?ItItItIt wonwonwonwont!t!t!t! LetLetLetLet memememe insertinsertinsertinsert datadatadatadata totototo anananan emptyemptyemptyempty partitionpartitionpartitionpartition p06:p06:p06:p06:

    SQL> insert into test_inc select rownum, sysdate+mod(rownum, 30),'wangweifengwangweifeng'||rownum,

    2 rpad('x', 50, 'x')||rownum, rpad('y', 50, 'z')||rownum, 6666 fromdual connect by rownum 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:36

    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:48

  • P06 300000 6796 2009-09-12 02:01:33

    7 rows selected.

    HowHowHowHow aboutaboutaboutabout IIII truncatetruncatetruncatetruncate allallallall tables?tables?tables?tables?LetLetLetLet memememe initializeinitializeinitializeinitialize thethethethe tabletabletabletable andandandand populatepopulatepopulatepopulate 2.12.12.12.1 millionmillionmillionmillion recordsrecordsrecordsrecords forforforfor 7777 partitions:partitions:partitions: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:18

    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 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:16

    7 rows selected.

    SQL> truncatetruncatetruncatetruncate tabletabletabletable test_inc;test_inc;test_inc;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 0000 0000 2009-09-12 04:09:43

    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 300000300000300000300000 6796679667966796 2009-09-12 03:53:58P01 300000300000300000300000 6796679667966796 2009-09-12 03:54:42P02 300000300000300000300000 6796679667966796 2009-09-12 03:55:24P03 300000300000300000300000 6796679667966796 2009-09-12 04:01:54P04 300000300000300000300000 6796679667966796 2009-09-12 04:03:33P05 300000300000300000300000 6796679667966796 2009-09-12 04:04:26P06 300000300000300000300000 6796679667966796 2009-09-12 04:05:16

    7 rows selected.

  • WeWeWeWe cancancancan see:see:see:see: thethethethe statisticsstatisticsstatisticsstatistics forforforfor tabletabletabletable levellevellevellevel isisisis gotgotgotgot updated,updated,updated,updated, but,but,but,but, itititit isisisis notnotnotnot gotgotgotgot updatedupdatedupdatedupdated forforforforpartitionpartitionpartitionpartition level!level!level!level!IIII think,think,think,think, itititit shouldshouldshouldshould bebebebe aaaa bug!bug!bug!bug! Anyway,Anyway,Anyway,Anyway, IIII willwillwillwill filefilefilefile TARTARTARTAR forforforfor OracleOracleOracleOracle forforforfor clarify.clarify.clarify.clarify.

    HowHowHowHow totototo fixfixfixfix itititit temporarily?temporarily?temporarily?temporarily? SetSetSetSet itititit backbackbackback totototo no-incrementalno-incrementalno-incrementalno-incremental,,,, thenthenthenthen analyzeanalyzeanalyzeanalyze again:again:again:again:SQL> execDBMS_STATS.SET_TABLE_PREFS(user,'test_inc','INCREMENTAL','FALSE''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')-----------------------------------------------------------------------FALSE

    SQL> 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 selected

    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 0 0 2009-09-12 04:18:34

    SQL> 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:34

    2.6.22.6.22.6.22.6.2 ForForForFor subpartitionsubpartitionsubpartitionsubpartition table,table,table,table, itititit isisisis totallytotallytotallytotally wrong:wrong:wrong: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'),

  • 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')---------------------------------------------------------------------TRUE

    SQL> insert into composite_rng_list select rownum, 'customer'||rownum, 'OR',to_date('2007-01-01', 'yyyy-mm-dd') from dual connect by rownum 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:58

    Elapsed: 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:57

    Elapsed: 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:55

    Then,Then,Then,Then, insertinsertinsertinsert 100000100000100000100000 moremoremoremore rowsrowsrowsrows andandandand analyzeanalyzeanalyzeanalyze again,again,again,again, wewewewe cancancancan seeseeseesee that,that,that,that, thethethethestatisticsstatisticsstatisticsstatistics atatatat partitionpartitionpartitionpartition levellevellevellevel andandandand tabletabletabletable levellevellevellevel werewerewerewere notnotnotnot changedchangedchangedchanged atatatat all:all:all: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 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:12

    SQL> 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

    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:24:11

    Then,Then,Then,Then, insertinsertinsertinsert 100000100000100000100000 moremoremoremore rowsrowsrowsrows andandandand analyzeanalyzeanalyzeanalyze again,again,again,again, wewewewe cancancancan seeseeseesee that,that,that,that, thethethethestatisticsstatisticsstatisticsstatistics atatatat partitionpartitionpartitionpartition levellevellevellevel andandandand tabletabletabletable levellevellevellevel werewerewerewere notnotnotnot changedchangedchangedchanged atatatat all:all:all: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 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:33

    SQL> 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

  • 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:32

    Also, I do more test on subpartitione table. It can not displayaccurate statistics on partition level and table level.

    2.6.32.6.32.6.32.6.3 ThereThereThereThere isisisis nononono incrementalincrementalincrementalincremental statisticsstatisticsstatisticsstatistics forforforfor partitionedpartitionedpartitionedpartitioned indexesindexesindexesindexes onononon partitionedpartitionedpartitionedpartitioned tables:tables:tables: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-142009-09-142009-09-142009-09-14 19:43:0119:43:0119:43:0119:43:01

    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 LAST_ANALYZEDFACTOR------------- ---------- ------------- ----------------- --------------P00 300000 300000 6763 2009-09-142009-09-142009-09-142009-09-14 19:54:3519:54:3519:54:3519:54:35P01 300000 300000 6763 2009-09-142009-09-142009-09-142009-09-14 19:54:3519:54:3519:54:3519:54:35

    Insert 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:50

    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-142009-09-142009-09-142009-09-14 20:00:5020:00:5020:00:5020:00:50P01 300000 300000 6763 2009-09-142009-09-142009-09-142009-09-14 20:00:5020:00:5020:00:5020:00:50P02 300000 300000 6763 2009-09-142009-09-142009-09-142009-09-14 20:00:5020:00:5020:00:5020:00:50

    ItItItIt seemsseemsseemsseems thatthatthatthat theretheretherethere isisisis nononono waywaywayway totototo setsetsetset indexindexindexindex ind_test_incind_test_incind_test_incind_test_inc asasasas incremental:incremental:incremental:incremental:SQL> select dbms_stats.get_prefs('incremental', 'wwf', 'test_inc') from dual;

    DBMS_STATS.GET_PREFS('INCREMENTAL','WWF','TEST_INC')

  • --------------------------------------------TRUE

    Elapsed: 00:00:00.01SQL> select dbms_stats.get_prefs('incremental', 'wwf', 'ind_test_inc''ind_test_inc''ind_test_inc''ind_test_inc') fromdual;

    DBMS_STATS.GET_PREFS('INCREMENTAL','WWF','IND_TEST_INC')-----------------------------------------------FALSE

    Elapsed: 00:00:00.01SQL> exec dbms_stats.set_table_prefs('wwf', 'ind_test_inc''ind_test_inc''ind_test_inc''ind_test_inc', 'incremental','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 1

    IIII willwillwillwill dodododo teststeststeststests onononon 11G11G11G11G ReleaseReleaseReleaseRelease 2222 onceonceonceonce itititit isisisis availableavailableavailableavailable forforforfor downloaddownloaddownloaddownload onononon SolarisSolarisSolarisSolaris version.version.version.version.But,But,But,But, fromfromfromfrom thethethethe documentdocumentdocumentdocument ofofofof 11G11G11G11G ReleaseReleaseReleaseRelease 2,2,2,2, whichwhichwhichwhich hashashashas beenbeenbeenbeen alreadyalreadyalreadyalready available,available,available,available, theretheretherethere isisisis stillstillstillstillnononono suchsuchsuchsuch functionfunctionfunctionfunction inininin suchsuchsuchsuch asasasas set_index_prefsset_index_prefsset_index_prefsset_index_prefs provided.provided.provided.provided.

    3.3.3.3. UnderUnderUnderUnder thethethethe hoodhoodhoodhood

    3.13.13.13.1 WhereWhereWhereWhere thethethethe synopsissynopsissynopsissynopsis exists?exists?exists?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

  • SM/ADVISOR Server Manageability - AdvisorFramework .016052246SM/AWR Server Manageability - Automatic WorkloadRepository .125610352SM/OPTSTATSM/OPTSTATSM/OPTSTATSM/OPTSTAT ServerServerServerServer ManageabilityManageabilityManageabilityManageability ---- OptimizerOptimizerOptimizerOptimizer StatisticsStatisticsStatisticsStatisticsHistoryHistoryHistoryHistory .115722656.115722656.115722656.115722656SM/OTHER Server Manageability - OtherComponents .00567627SMON_SCN_TIME Transaction Layer - SCN to TIMEmapping .003173828JOB_SCHEDULER Unified JobScheduler .000610352

    29 rows selected.

    TheTheTheThe blueblueblueblue linelinelineline representsrepresentsrepresentsrepresents thethethethe spacespacespacespace occupiedoccupiedoccupiedoccupied bybybyby thethethethe synopsissynopsissynopsissynopsis forforforfor globalglobalglobalglobal levellevellevellevel statistics.statistics.statistics.statistics.Usually,Usually,Usually,Usually, itititit willwillwillwill onlyonlyonlyonly consumeconsumeconsumeconsume veryveryveryvery littlelittlelittlelittle space.space.space.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$SYS.OPTSTAT_USER_PREFS$SYS.OPTSTAT_USER_PREFS$SYS.OPTSTAT_USER_PREFS$ a, obj$ bwhere a.obj# = b.obj#;

    OBJ# NAME PNAME VALCHAR---------- ------------------------------ -------------------- ----------------

    15307 TEST_INC INCREMENTAL TRUE

    InInInIn fact,fact,fact,fact, forforforfor aaaa partitionedpartitionedpartitionedpartitioned table,table,table,table, thethethethe globalglobalglobalglobal levellevellevellevel NDVNDVNDVNDV (Number(Number(Number(Number ofofofof DistinctDistinctDistinctDistinct Value)Value)Value)Value) ofofofofcolumnscolumnscolumnscolumns isisisis thethethethe mostmostmostmost challengeable.challengeable.challengeable.challengeable. AllAllAllAll otherotherotherother statisticsstatisticsstatisticsstatistics cancancancan bebebebe speculatedspeculatedspeculatedspeculated fromfromfromfrom partitionpartitionpartitionpartitionlevel,level,level,level, suchsuchsuchsuch asasasas num_rows,num_rows,num_rows,num_rows, blocks,blocks,blocks,blocks, avg_row_len.avg_row_len.avg_row_len.avg_row_len. So,So,So,So, IIII think,think,think,think, thisthisthisthis isisisis whatwhatwhatwhat OracleOracleOracleOracle 11G11G11G11G ReleaseReleaseReleaseRelease2222 enhances.enhances.enhances.enhances.

    4.4.4.4. MyMyMyMy conclusion:conclusion:conclusion:conclusion:

    IIII think,think,think,think, incrementalincrementalincrementalincremental statisticsstatisticsstatisticsstatistics gatheringgatheringgatheringgathering forforforfor partitionedpartitionedpartitionedpartitioned tablestablestablestables isisisis aaaa veryveryveryvery usefulusefulusefuluseful newnewnewnew featurefeaturefeaturefeatureintroducedintroducedintroducedintroduced bybybyby ORACLEORACLEORACLEORACLE 11G11G11G11G ifififif allallallall thethethethe bugsbugsbugsbugs cancancancan bebebebe resolved.resolved.resolved.resolved.ItItItIt willwillwillwill consumeconsumeconsumeconsume muchmuchmuchmuch lesslesslessless resourceresourceresourceresource especiallyespeciallyespeciallyespecially forforforfor largelargelargelarge partitioned/subpartitionedpartitioned/subpartitionedpartitioned/subpartitionedpartitioned/subpartitioned tablestablestablestablesandandandand shortenshortenshortenshorten ourourourour statisticsstatisticsstatisticsstatistics gatheringgatheringgatheringgathering process.process.process.process. IIII believebelievebelievebelieve itititit willwillwillwillnotnotnotnot onlyonlyonlyonly helphelphelphelp usususus forforforfor ourourourour normalnormalnormalnormal analyzeanalyzeanalyzeanalyze CR,CR,CR,CR, butbutbutbut alsoalsoalsoalso itititit willwillwillwill helphelphelphelp usususus underunderunderunder situationssituationssituationssituations underunderunderundertoughtoughtoughtough situationssituationssituationssituations (such(such(such(such asasasas TCB)TCB)TCB)TCB) causedcausedcausedcaused bybybyby inaccurateinaccurateinaccurateinaccurate statistics,statistics,statistics,statistics,asasasas atatatat suchsuchsuchsuch situations,situations,situations,situations, timetimetimetime isisisis sosososo preciouspreciouspreciousprecious forforforfor us.us.us.us.

    Anyway,Anyway,Anyway,Anyway, IIII willwillwillwill tracktracktracktrack thisthisthisthis feature.feature.feature.feature.

    Thanks!Thanks!Thanks!Thanks!