Monday, January 31, 2011

Import Table Statistics to Another Table

It’s been a long time since I posted on my blog. This post is in response to the question that I received through email:

<<

Just like to know if I can use dbms_stats.import_table_stats to import table statistics to another table?

I am wondering if I can import table statistics from T1 to T2 using dbms_stats package?.

>>

The simple answer to the above question is “NO”. You cannot copy statistics to a different table even if they are identical. However, there are two ways of achieving this:

1) Temporarily rename the destination table (T_IDENTICAL) as original table (T) and import statistics or

2) Break into the statistics table.

Option -1 is pretty straight forward so we will not discuss that. Let’s see how to break into statistics table.

Let us create the two tables: source table “T” and the destination table “T_IDENTICAL”. I am creating both these tables in the same schema, so as to avoid exporting and importing of statistics table.

SQL>
SQL> drop table t purge;

Table dropped.

SQL> drop table t_identical purge;

Table dropped.

SQL>
SQL> create table t as select rownum id, object_name name from all_objects where rownum < 1001;

Table created.

SQL>
SQL> create table t_identical as select * from t where 1=2;

Table created.

SQL>
SQL>
Collect statistics for the source table (T)
SQL>
SQL> exec dbms_stats.gather_table_stats(user, 't');
PL/SQL procedure successfully completed.
SQL>
SQL> select table_name, num_rows from user_tables where table_name in ('T', 'T_IDENTICAL');
TABLE_NAME                       NUM_ROWS
------------------------------ ----------
T                                    1000
T_IDENTICAL
SQL>

Create a statistics table (“MY_STATS_TAB”) and export statistics of the source table “T”.

SQL>
SQL> exec dbms_stats.create_stat_table('TEST','MY_STATS_TAB');
PL/SQL procedure successfully completed.
SQL> exec dbms_stats.export_table_stats('TEST','T',NULL,'MY_STATS_TAB');
PL/SQL procedure successfully completed.
SQL>

Now let us try to import statistics to the destination table (T_IDENTICAL):

SQL> exec dbms_stats.import_table_stats('TEST','T_IDENTICAL', null, 'MY_STATS_TAB');
PL/SQL procedure successfully completed.
SQL>
SQL>
SQL> select table_name, num_rows from user_tables where table_name in ('T', 'T_IDENTICAL');
TABLE_NAME                       NUM_ROWS
------------------------------ ----------
T                                    1000
T_IDENTICAL
SQL>

No affect. 

Oracle simply ignored my request without reporting any errors.

As we have source table statistics in a safe place, let us delete statistics from the source table and import them back from the container table. (This step ensures stats import is working as expected)

SQL> exec dbms_stats.delete_table_stats(user, 'T');

PL/SQL procedure successfully completed.

SQL> select table_name, num_rows from user_tables where table_name in ('T', 'T_IDENTICAL');

TABLE_NAME                       NUM_ROWS
------------------------------ ----------
T
T_IDENTICAL

SQL>

SQL>
SQL> exec dbms_stats.import_table_stats('TRADE','T', null, 'MY_STATS_TAB');

PL/SQL procedure successfully completed.

SQL> select table_name, num_rows from user_tables where table_name in ('T', 'T_IDENTICAL');

TABLE_NAME                       NUM_ROWS
------------------------------ ----------
T                                    1000
T_IDENTICAL

SQL>
SQL>

As you can see, import works only when the source and destination tables are same.

Let us see what’s there in the MY_STATS_TABLE:

SQL>
SQL> select count(*) from my_stats_tab;

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

SQL>
SQL>
SQL> select c1, c5 from my_stats_tab;

C1                             C5
------------------------------ ------------------
T                              TRADE
T                              TRADE
T                              TRADE

SQL>
SQL>

Columns “C5” and “C1” of the statistics table represent schema owner and table name respectively. Let us update the table name from “T” to “T_IDENTICAL”.

SQL> update my_stats_tab set c1 = 'T_IDENTICAL';

3 rows updated.

SQL> commit;

Commit complete.

SQL>

Now import the table statistics for “T_IDENTICAL” table

SQL> select table_name, num_rows from user_tables where table_name in ('T', 'T_IDENTICAL');

TABLE_NAME                       NUM_ROWS
------------------------------ ----------
T                                    1000
T_IDENTICAL

SQL>
SQL> exec dbms_stats.import_table_stats('TRADE','T_IDENTICAL', null, 'MY_STATS_TAB');

PL/SQL procedure successfully completed.

SQL> select table_name, num_rows from user_tables where table_name in ('T', 'T_IDENTICAL');

TABLE_NAME                       NUM_ROWS
------------------------------ ----------
T                                    1000
T_IDENTICAL                          1000

SQL>
SQL>

There you go. We were able to successfully move statistics to another table by hacking into the statistics table.

Hope you enjoyed this post.

Thursday, December 02, 2010

I bet you haven't seen 62 hours of AWR Report

One of my customers is having extreme performance issues during batch load. The batch is consuing around 6 hours to complete which is supposed to complete in less than 90 minutes.

The guys shared their AWR report with us and here is the snapshot information for you guys:


              Snap Id      Snap Time      Sessions Curs/Sess
            --------- ------------------- -------- ---------
Begin Snap:      4621 27-Nov-10 00:00:09        30       1.3
  End Snap:      4683 29-Nov-10 14:00:51        30       2.0
   Elapsed:            3,720.70 (mins)
   DB Time:            3,021.65 (mins)

This report is for whopping 62 hours. This long report results in a meaningless data as everything is averaged out and one doesn't see the real issues.

With this information at hand I can say:

1) Mostly likely they haven't changed the default AWR snapshot duration (i.e. 1 hour)

2) I would then request the guys to generate hourly AWR reports during the time they were experiencing extreme performance issues.

3) Lastly, suggest them to change the snapshot duration from (default) 1 hour to 15 mintues.

Saturday, November 27, 2010

Oracle Database 11g R2: Interactive Quick Reference

Oracle has released "Interactive Quick Reference" for DBA's and Developer's to better understand Oracle Database architecture. It includes

1) List of DBA Views,

2) Database Architecture Diagram, and

3) List of all Database Background Processes by category.

Click here to read more about it and click here to download it.