In my previous blog I showed how you can save your current optimiser stats into a seperate table whenever you refresh them, so that they can be restored should the new statistics lead to poor SQL execution plans. Oracle have added an improved version of this facility to 10g (which I take as a sign that this is a significant issue for their customers). There’s more information in the documentation, here for example, but here’s how it looks in action.
SQL> select table_name, num_rows from user_tablesThe user_tab_stats_history view shows the different versions of table statistics that have been saved. In this case, there aren’t any yet. However, the current statistics will be saved when I regenerate the schema statistics next. (Note that there is no need for me to specify a stats table in the call to gather_schema_stats and that this call should all be one one line.)
2 /
SQL> select count(*) from temp;
COUNT(*)
———-
1000000
SQL> select * from user_tab_stats_history;
no rows selected
SQL> exec dbms_stats.gather_schema_stats ( ownname=>’TESTUSER’, estimate_percent=>10)Now I’ll truncate a couple of tables and regenerate the schema statistics.
PL/SQL procedure successfully completed.
SQL> select table_name, stats_update_time
from user_tab_stats_history;
TABLE_NAME
——————————
STATS_UPDATE_TIME
——————————————————
TEMP
18-JUN-06 04.49.10.036992 PM +01:00
TEST_TAB1
18-JUN-06 05.05.55.447281 PM +01:00
TEST_TAB2
18-JUN-06 05.20.04.831991 PM +01:00
DUDE
18-JUN-06 04.49.06.665160 PM +01:00
SQL> truncate table test_tab1;There are two saved versions now and the current statistics show zero rows in test_tab1 and test_tab2.
Table truncated.
SQL> truncate table test_tab2;
Table truncated.
SQL> exec dbms_stats.gather_schema_stats( ownname=>’TESTUSER’, estimate_percent=>10)
PL/SQL procedure successfully completed.
SQL> select table_name, stats_update_time from user_tab_stats_history;
TABLE_NAME
——————————
STATS_UPDATE_TIME
—————————————————————-
TEMP
18-JUN-06 04.49.10.036992 PM +01:00
TEST_TAB1
18-JUN-06 05.05.55.447281 PM +01:00
TEST_TAB2
18-JUN-06 05.20.04.831991 PM +01:00
DUDE
18-JUN-06 05.22.41.565053 PM +01:00
TEMP
18-JUN-06 05.22.49.773888 PM +01:00
TEST_TAB1
18-JUN-06 05.22.49.798122 PM +01:00
TEST_TAB2
18-JUN-06 05.22.49.823022 PM +01:00
DUDE
18-JUN-06 04.49.06.665160 PM +01:00
8 rows selected.
SQL> select table_name, num_rows from user_tables;If I want to go back to the previous version of the statistics, I can use the restore_schema_stats procedure (the documentation describes various other restore procedures). Here, I’ll just say ‘restore the statistics as they looked yesterday’.
SQL> exec dbms_stats.restore_schema_stats( ownname=>’TESTUSER’, as_of_timestamp=>sysdate-1);The statistics suggest that there are 65 million rows in test_tab1 and test_tab2 (of course, the tables are actually empty - but Oracle is just following my instructions). To keep everything neat and tidy, there are new entries in the history table to reflect the fact that I just changed the statistics again.
PL/SQL procedure successfully completed.
SQL> select table_name, num_rows from user_tables;
SQL> select table_name, stats_update_time from user_tab_stats_history;
TABLE_NAME
——————————
STATS_UPDATE_TIME
————————————————————–
TEMP
18-JUN-06 04.49.10.036992 PM +01:00
TEST_TAB1
18-JUN-06 05.05.55.447281 PM +01:00
TEST_TAB2
18-JUN-06 05.20.04.831991 PM +01:00
DUDE
18-JUN-06 05.22.41.565053 PM +01:00
TEMP
18-JUN-06 05.22.49.773888 PM +01:00
TEST_TAB1
18-JUN-06 05.22.49.798122 PM +01:00
TEST_TAB2
18-JUN-06 05.22.49.823022 PM +01:00
DUDE
18-JUN-06 05.49.06.966851 PM +01:00
TEMP
18-JUN-06 05.49.07.230811 PM +01:00
TEST_TAB1
18-JUN-06 05.49.07.272036 PM +01:00
TEST_TAB2
18-JUN-06 05.49.07.290720 PM +01:00
DUDE
18-JUN-06 04.49.06.665160 PM +01:00
12 rows selected.
No comments:
Post a Comment