dbms_stats.set_table_stats “defaults” June 21, 2010
Posted by mwidlake in internals, statistics.Tags: performance, SQL, statistics
trackback
What happens if you call dbms_stats.set_table_stats without passing in any of the values to set?
I know, why would you do it anyway? Well, I did so by accident. If I want to gather quick stats on a test table I execute something like:
exec dbms_stats.gather_table_stats(OWNNAME =>user,TABNAME =>’TEST_TAB1′)
If I am feeling generous I might state ESTIMATE_PERCENT too.
I was doing some testing work and was gathering stats and also setting stats manually. Then I started to see several of my test tables all had 2000 rows and were 100 blocks in size – at least according to the stats. I knew this was not possible. It turned out to be Cut ‘n’ Paste fingerf the trouble and I was issuing.
exec dbms_stats.set_table_stats(OWNNAME =>user,TABNAME =>’TEST_TAB1′)
If the table did not already have stats this set the stats on the table to default values of 2000 rows, 100 blocks. If the table already had stats then they were left as they were.
If those figures ring a bell, then that is because they are the default values used if a table has no stats and you have no dynamic sampling. See this table of defaults
Anyway, below is a little worked example of these default values being set. Oh, version is 10.2.0.3.
TDB> drop table TEST1 purge 2 / TDB> select sysdate from dual; SYSDATE ----------------- 21-JUN-2010 16:52 TDB> CREATE TABLE TEST1 2 AS SELECT ROWNUM ID 3 ,OBJECT_NAME OBJ_NAME 4 FROM DBA_OBJECTS TDB> SELECT TABLE_NAME,NUM_ROWS,BLOCKS,SAMPLE_SIZE 2 FROM DBA_TABLES 3 WHERE OWNER=USER AND TABLE_NAME = 'TEST1' 4 / TABLE_NAME NUM_ROWS BLOCKS SAMPLE_SIZE ------------------------------ ---------- ---------- ----------- TEST1 -- New table, no stats yet gathered, the columns hold null -- Call dbms_stats.SET_TABLE_STATS, setting nothing TDB> EXEC dbms_stats.set_table_stats(ownname => user,tabname => 'TEST1') TDB> SELECT TABLE_NAME,NUM_ROWS,BLOCKS,SAMPLE_SIZE 2 FROM DBA_TABLES 3 WHERE OWNER=USER AND TABLE_NAME = 'TEST1' TABLE_NAME NUM_ROWS BLOCKS SAMPLE_SIZE ------------------------------ ---------- ---------- ----------- TEST1 2000 100 2000 -- The columns are set to defaults -- Gather proper stats TDB> exec dbms_stats.gather_table_stats(ownname =>user,tabname =>'TEST1',estimate_percent=>10) TABLE_NAME NUM_ROWS BLOCKS SAMPLE_SIZE ------------------------------ ---------- ---------- ----------- TEST1 205430 956 20543 -- Now use SET_TABLE_STATS as intended, setting numrows to a value TDB> EXEC dbms_stats.set_table_stats(ownname => user,tabname => 'TEST1',numrows=>5000) TABLE_NAME NUM_ROWS BLOCKS SAMPLE_SIZE ------------------------------ ---------- ---------- ----------- TEST1 5000 956 20543 -- Try the naked SET_TABLE_STATS TDB> EXEC dbms_stats.set_table_stats(ownname => user,tabname => 'TEST1') TABLE_NAME NUM_ROWS BLOCKS SAMPLE_SIZE ------------------------------ ---------- ---------- ----------- TEST1 5000 956 20543 TDB> select sysdate from dual; Any Key> SYSDATE ----------------- 21-JUN-2010 16:52 -- And let us see how the stats have changed over the last few minutes. TDB> select table_name,stats_update_time 2 from dba_tab_stats_history 3 where table_name = 'TEST1' 4 / Any Key> TABLE_NAME STATS_UPDATE_TIME ------------------------------ -------------------------------- TEST1 21-JUN-10 16.52.03.028086 +00:00 TEST1 21-JUN-10 16.52.05.109905 +00:00 TEST1 21-JUN-10 16.52.06.906204 +00:00 TEST1 21-JUN-10 16.52.08.329664 +00:00

Comments»
No comments yet — be the first.