Monday, July 14, 2014

Incremental stats gathering changed up in 11.2.0.4

When upgrading from 11.2.0.2 to 11.2.0.4 from a customer application, accidently saw the Incremental stats gathering feature got messed up in 11.2.0.4 (even in 12c too)

The "incremental statistics” feature stores "synopses" of each column of each partition in the data dictionary, and then runs a query that (roughly speaking) aggregates the synopses for each column across partitions to produce a synopsis fir the table. This allows Oracle to get an accurate estimate of the number of distinct values for the column without having to take a large sample of the table.

apps@DVDV01> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE    11.2.0.2.0      Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production

5 rows selected.

apps@DVDV01>
apps@DVDV01> create table t
  2  partition by list(x)
  3  (
  4     partition p1 values (1),
  5     partition p2 values (2)
  6  )
  7  as
  8  select a.*, mod(rownum,2)+1 x ,
  9     (mod(rownum,2)+1)*5 as order_status
 10  from all_objects a;

Table created.

apps@DVDV01> exec dbms_stats.set_table_prefs(user,'T','INCREMENTAL','TRUE');

PL/SQL procedure successfully completed.

apps@DVDV01> exec dbms_stats.set_table_prefs(user,'T','GRANULARITY','auto');

PL/SQL procedure successfully completed.

apps@DVDV01> exec dbms_stats.set_table_prefs(user,'T','PUBLISH','TRUE');

PL/SQL procedure successfully completed.

apps@DVDV01> exec dbms_stats.set_table_prefs(user,'T','ESTIMATE_PERCENT','dbms_stats.auto_sample_size');

PL/SQL procedure successfully completed.
apps@DVDV01> select dbms_stats.get_prefs('INCREMENTAL',user,'T') incremental,
  2        dbms_stats.get_prefs('GRANULARITY',user,'T') granularity,
  3        dbms_stats.get_prefs('PUBLISH',user,'T') publish,
  4        dbms_stats.get_prefs('ESTIMATE_PERCENT',user,'T') estimate_percent
  5  from dual ;

INCREMENTA GRANULARIT PUBLISH    ESTIMATE_P
---------- ---------- ---------- ----------
TRUE       AUTO       TRUE       DBMS_STATS.AUTO_SAMPLE_SIZE

1 row selected.

apps@DVDV01> exec dbms_stats.gather_table_Stats(user,'T');

PL/SQL procedure successfully completed.

apps@DVDV01> select table_name,partition_name,last_analyzed
  2  from user_tab_partitions
  3  where table_name ='T' ;

TABLE_NAME PARTITION_ LAST_ANALYZED
---------- ---------- -----------------------
T          P1         14-JUL-2014 02:19:28 AM
T          P2         14-JUL-2014 02:19:28 AM

2 rows selected.

apps@DVDV01> select table_name,column_name,num_distinct,
  2      last_analyzed
  3  from user_TAB_col_statistics
  4  where table_name ='T'
  5  order by column_name;

TABLE_NAME COLUMN_NAME     NUM_DISTINCT LAST_ANALYZED
---------- --------------- ------------ -----------------------
T          CREATED                 3849 14-JUL-2014 02:19:28 AM
T          DATA_OBJECT_ID         39130 14-JUL-2014 02:19:28 AM
T          EDITION_NAME               0 14-JUL-2014 02:19:28 AM
T          GENERATED                  2 14-JUL-2014 02:19:28 AM
T          LAST_DDL_TIME           3651 14-JUL-2014 02:19:28 AM
T          NAMESPACE                 12 14-JUL-2014 02:19:28 AM
T          OBJECT_ID             101253 14-JUL-2014 02:19:28 AM
T          OBJECT_NAME            42484 14-JUL-2014 02:19:28 AM
T          OBJECT_TYPE               32 14-JUL-2014 02:19:28 AM
T          ORDER_STATUS               2 14-JUL-2014 02:19:28 AM
T          OWNER                     28 14-JUL-2014 02:19:28 AM
T          SECONDARY                  2 14-JUL-2014 02:19:28 AM
T          STATUS                     2 14-JUL-2014 02:19:28 AM
T          SUBOBJECT_NAME         13799 14-JUL-2014 02:19:28 AM
T          TEMPORARY                  2 14-JUL-2014 02:19:28 AM
T          TIMESTAMP               4065 14-JUL-2014 02:19:28 AM
T          X                          2 14-JUL-2014 02:19:28 AM

17 rows selected.

apps@DVDV01>

So far everything looks fine; we have couple of partition with stats gathered perfectly.

apps@DVDV01> update t set order_status = 77
  2  where x = 1 and rownum = 1;

1 row updated.

apps@DVDV01> commit;

Commit complete.

apps@DVDV01>

This update is done purposefully since the min or max value for a column could change after the update in the table

apps@DVDV01> alter table t add partition p3 values(3);

Table altered.

apps@DVDV01> insert into t
  2  select a.*, 3 as id,
  3     (mod(rownum,3)+1)*5 as order_status
  4  from all_objects a
  5  where rownum <=1000;

1000 rows created.

apps@DVDV01> commit;

Commit complete.

apps@DVDV01>

Now added a bunch of records to new partitions, and updated few rows into existing partitions, when stats gathered P1 and P3 got modified (since data changed only on those partition) without touching partition P2.

apps@DVDV01> exec dbms_stats.gather_table_Stats(user,'T');

PL/SQL procedure successfully completed.

apps@DVDV01>
apps@DVDV01> select table_name,partition_name,last_analyzed
  2  from user_tab_partitions
  3  where table_name ='T' ;

TABLE_NAME PARTITION_ LAST_ANALYZED
---------- ---------- -----------------------
T          P1         14-JUL-2014 02:19:49 AM
T          P2         14-JUL-2014 02:19:28 AM
T          P3         14-JUL-2014 02:19:48 AM

3 rows selected.

apps@DVDV01>
apps@DVDV01> select table_name,column_name,num_distinct,
  2      last_analyzed
  3  from user_TAB_col_statistics
  4  where table_name ='T'
  5  order by column_name;

TABLE_NAME COLUMN_NAME     NUM_DISTINCT LAST_ANALYZED
---------- --------------- ------------ -----------------------
T          CREATED                 3849 14-JUL-2014 02:19:49 AM
T          DATA_OBJECT_ID         39130 14-JUL-2014 02:19:49 AM
T          EDITION_NAME               0 14-JUL-2014 02:19:49 AM
T          GENERATED                  2 14-JUL-2014 02:19:49 AM
T          LAST_DDL_TIME           3651 14-JUL-2014 02:19:49 AM
T          NAMESPACE                 12 14-JUL-2014 02:19:49 AM
T          OBJECT_ID             101696 14-JUL-2014 02:19:49 AM
T          OBJECT_NAME            42484 14-JUL-2014 02:19:49 AM
T          OBJECT_TYPE               32 14-JUL-2014 02:19:49 AM
T          ORDER_STATUS               4 14-JUL-2014 02:19:49 AM
T          OWNER                     28 14-JUL-2014 02:19:49 AM
T          SECONDARY                  2 14-JUL-2014 02:19:49 AM
T          STATUS                     2 14-JUL-2014 02:19:49 AM
T          SUBOBJECT_NAME         13799 14-JUL-2014 02:19:49 AM
T          TEMPORARY                  2 14-JUL-2014 02:19:49 AM
T          TIMESTAMP               4065 14-JUL-2014 02:19:49 AM
T          X                          3 14-JUL-2014 02:19:49 AM

17 rows selected.

apps@DVDV01>

So everything works expected in 11.2.0.2, but see what happens in 11.2.0.4 and 12.1.0.1

rajesh@ORA11G> select * from v$version ;

BANNER
-----------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE    11.2.0.4.0      Production
TNS for 64-bit Windows: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

5 rows selected.

rajesh@ORA11G>
rajesh@ORA11G> select table_name,partition_name,last_analyzed
  2  from user_tab_partitions
  3  where table_name ='T' ;

TABLE_NAME PARTITION_ LAST_ANALYZED
---------- ---------- -----------------------
T          P1         14-JUL-2014 12:51:51 PM
T          P2         14-JUL-2014 12:51:51 PM

2 rows selected.

rajesh@ORA11G> select table_name,column_name,num_distinct,
  2      last_analyzed
  3  from user_TAB_col_statistics
  4  where table_name ='T'
  5  order by column_name;

TABLE_NAME COLUMN_NAME     NUM_DISTINCT LAST_ANALYZED
---------- --------------- ------------ -----------------------
T          CREATED                 1340 14-JUL-2014 12:51:52 PM
T          DATA_OBJECT_ID          7069 14-JUL-2014 12:51:52 PM
T          EDITION_NAME               0 14-JUL-2014 12:51:52 PM
T          GENERATED                  2 14-JUL-2014 12:51:52 PM
T          LAST_DDL_TIME           1404 14-JUL-2014 12:51:52 PM
T          NAMESPACE                 17 14-JUL-2014 12:51:52 PM
T          OBJECT_ID              84753 14-JUL-2014 12:51:52 PM
T          OBJECT_NAME            49944 14-JUL-2014 12:51:52 PM
T          OBJECT_TYPE               39 14-JUL-2014 12:51:52 PM
T          ORDER_STATUS               2 14-JUL-2014 12:51:52 PM
T          OWNER                     32 14-JUL-2014 12:51:52 PM
T          SECONDARY                  2 14-JUL-2014 12:51:52 PM
T          STATUS                     2 14-JUL-2014 12:51:52 PM
T          SUBOBJECT_NAME           196 14-JUL-2014 12:51:52 PM
T          TEMPORARY                  2 14-JUL-2014 12:51:52 PM
T          TIMESTAMP               1496 14-JUL-2014 12:51:52 PM
T          X                          2 14-JUL-2014 12:51:52 PM

17 rows selected.

rajesh@ORA11G> update t set order_status = 77
  2  where x = 1 and rownum = 1;

1 row updated.

rajesh@ORA11G> commit;

Commit complete.

rajesh@ORA11G> alter table t add partition p3 values(3);

Table altered.

rajesh@ORA11G> insert into t
  2  select a.*, 3 as id,
  3     (mod(rownum,3)+1)*5 as order_status
  4  from all_objects a
  5  where rownum <=1000;

1000 rows created.

rajesh@ORA11G> commit;

Commit complete.

rajesh@ORA11G> exec dbms_stats.gather_table_Stats(user,'T');

PL/SQL procedure successfully completed.

rajesh@ORA11G> select table_name,partition_name,last_analyzed
  2  from user_tab_partitions
  3  where table_name ='T' ;

TABLE_NAME PARTITION_ LAST_ANALYZED
---------- ---------- -----------------------
T          P1         14-JUL-2014 12:52:13 PM
T          P2         14-JUL-2014 12:52:15 PM
T          P3         14-JUL-2014 12:52:15 PM

3 rows selected.
rajesh@ORA11G> select table_name,column_name,num_distinct,
  2      last_analyzed
  3  from user_TAB_col_statistics
  4  where table_name ='T'
  5  order by column_name;

TABLE_NAME COLUMN_NAME     NUM_DISTINCT LAST_ANALYZED
---------- --------------- ------------ -----------------------
T          CREATED                 1340 14-JUL-2014 12:52:15 PM
T          DATA_OBJECT_ID          7069 14-JUL-2014 12:52:15 PM
T          EDITION_NAME               0 14-JUL-2014 12:52:15 PM
T          GENERATED                  2 14-JUL-2014 12:52:15 PM
T          LAST_DDL_TIME           1404 14-JUL-2014 12:52:15 PM
T          NAMESPACE                 17 14-JUL-2014 12:52:15 PM
T          OBJECT_ID              84932 14-JUL-2014 12:52:15 PM
T          OBJECT_NAME            49944 14-JUL-2014 12:52:15 PM
T          OBJECT_TYPE               39 14-JUL-2014 12:52:15 PM
T          ORDER_STATUS               4 14-JUL-2014 12:52:15 PM
T          OWNER                     32 14-JUL-2014 12:52:15 PM
T          SECONDARY                  2 14-JUL-2014 12:52:15 PM
T          STATUS                     2 14-JUL-2014 12:52:15 PM
T          SUBOBJECT_NAME           196 14-JUL-2014 12:52:15 PM
T          TEMPORARY                  2 14-JUL-2014 12:52:15 PM
T          TIMESTAMP               1496 14-JUL-2014 12:52:15 PM
T          X                          3 14-JUL-2014 12:52:15 PM

17 rows selected.

rajesh@ORA11G>

So even though data not changed in partition P2 It got analyzed.  We can see the same thing happening in Oracle 12c too.

rajesh@PDB1> select * from v$version;

BANNER
------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
PL/SQL Release 12.1.0.1.0 - Production
CORE    12.1.0.1.0      Production
TNS for 64-bit Windows: Version 12.1.0.1.0 - Production
NLSRTL Version 12.1.0.1.0 - Production

5 rows selected.

rajesh@PDB1>
rajesh@PDB1> select table_name,partition_name,last_analyzed
  2  from user_tab_partitions
  3  where table_name ='T' ;

TABLE_NAME PARTITION_ LAST_ANALYZED
---------- ---------- -----------------------
T          P1         14-JUL-2014 01:08:42 PM
T          P2         14-JUL-2014 01:08:40 PM

2 rows selected.

rajesh@PDB1>
rajesh@PDB1> select table_name,column_name,num_distinct,
  2      last_analyzed
  3  from user_TAB_col_statistics
  4  where table_name ='T'
  5  order by column_name;

TABLE_NAME COLUMN_NAME     NUM_DISTINCT LAST_ANALYZED
---------- --------------- ------------ -----------------------
T          CREATED                 1513 14-JUL-2014 01:08:42 PM
T          DATA_OBJECT_ID          6321 14-JUL-2014 01:08:42 PM
T          EDITIONABLE                2 14-JUL-2014 01:08:42 PM
T          EDITION_NAME               0 14-JUL-2014 01:08:42 PM
T          GENERATED                  2 14-JUL-2014 01:08:42 PM
T          LAST_DDL_TIME           1687 14-JUL-2014 01:08:42 PM
T          NAMESPACE                 18 14-JUL-2014 01:08:42 PM
T          OBJECT_ID              89720 14-JUL-2014 01:08:42 PM
T          OBJECT_NAME            51544 14-JUL-2014 01:08:42 PM
T          OBJECT_TYPE               40 14-JUL-2014 01:08:42 PM
T          ORACLE_MAINTAIN            2 14-JUL-2014 01:08:42 PM
           ED

T          ORDER_STATUS               2 14-JUL-2014 01:08:42 PM
T          OWNER                     32 14-JUL-2014 01:08:42 PM
T          SECONDARY                  2 14-JUL-2014 01:08:42 PM
T          SHARING                    3 14-JUL-2014 01:08:42 PM
T          STATUS                     1 14-JUL-2014 01:08:42 PM
T          SUBOBJECT_NAME           348 14-JUL-2014 01:08:42 PM
T          TEMPORARY                  2 14-JUL-2014 01:08:42 PM
T          TIMESTAMP               1726 14-JUL-2014 01:08:42 PM
T          X                          2 14-JUL-2014 01:08:42 PM

20 rows selected.

rajesh@PDB1> update t set order_status = 77
  2  where x = 1 and rownum = 1;

1 row updated.

rajesh@PDB1> commit;

Commit complete.

rajesh@PDB1>
rajesh@PDB1> alter table t add partition p3 values(3);

Table altered.

rajesh@PDB1> insert into t
  2  select a.*, 3 as id,
  3     (mod(rownum,3)+1)*5 as order_status
  4  from all_objects a
  5  where rownum <=1000;

1000 rows created.

rajesh@PDB1> commit;

Commit complete.

rajesh@PDB1>
rajesh@PDB1> exec dbms_stats.gather_table_Stats(user,'T');

PL/SQL procedure successfully completed.

rajesh@PDB1>
rajesh@PDB1> select table_name,partition_name,last_analyzed
  2  from user_tab_partitions
  3  where table_name ='T' ;

TABLE_NAME PARTITION_ LAST_ANALYZED
---------- ---------- -----------------------
T          P1         14-JUL-2014 01:09:06 PM
T          P2         14-JUL-2014 01:09:06 PM
T          P3         14-JUL-2014 01:09:06 PM

3 rows selected.

rajesh@PDB1>
rajesh@PDB1> select table_name,column_name,num_distinct,
  2      last_analyzed
  3  from user_TAB_col_statistics
  4  where table_name ='T'
  5  order by column_name;

TABLE_NAME COLUMN_NAME     NUM_DISTINCT LAST_ANALYZED
---------- --------------- ------------ -----------------------
T          CREATED                 1513 14-JUL-2014 01:09:07 PM
T          DATA_OBJECT_ID          6321 14-JUL-2014 01:09:07 PM
T          EDITIONABLE                2 14-JUL-2014 01:09:07 PM
T          EDITION_NAME               0 14-JUL-2014 01:09:07 PM
T          GENERATED                  2 14-JUL-2014 01:09:07 PM
T          LAST_DDL_TIME           1687 14-JUL-2014 01:09:07 PM
T          NAMESPACE                 18 14-JUL-2014 01:09:07 PM
T          OBJECT_ID              90148 14-JUL-2014 01:09:07 PM
T          OBJECT_NAME            51544 14-JUL-2014 01:09:07 PM
T          OBJECT_TYPE               40 14-JUL-2014 01:09:07 PM
T          ORACLE_MAINTAIN            2 14-JUL-2014 01:09:07 PM
           ED

T          ORDER_STATUS               4 14-JUL-2014 01:09:07 PM
T          OWNER                     32 14-JUL-2014 01:09:07 PM
T          SECONDARY                  2 14-JUL-2014 01:09:07 PM
T          SHARING                    3 14-JUL-2014 01:09:07 PM
T          STATUS                     1 14-JUL-2014 01:09:07 PM
T          SUBOBJECT_NAME           348 14-JUL-2014 01:09:07 PM
T          TEMPORARY                  2 14-JUL-2014 01:09:07 PM
T          TIMESTAMP               1726 14-JUL-2014 01:09:07 PM
T          X                          3 14-JUL-2014 01:09:07 PM

20 rows selected.


Seems to be we are hitting up a Bug 16726844 - Statistics may be re-gathered on partitions that have no changes (Doc ID 16726844.8) – But not sure.

No comments:

Post a Comment