05.11.2015 Views

Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

CHAPTER 10 ■ DATABASE TABLES 409<br />

As we can see, only the EMP table was analyzed in this case; the two global temporary<br />

tables were ignored. We can change that behavior by calling GATHER_SCHEMA_STATS with<br />

GATHER_TEMP => TRUE:<br />

ops$tkyte@ORA10G> insert into gtt2 select user_id from all_users;<br />

38 rows created.<br />

ops$tkyte@ORA10G> exec dbms_stats.gather_schema_stats( user, gather_temp=>TRUE );<br />

PL/SQL procedure successfully completed.<br />

ops$tkyte@ORA10G> select table_name, last_analyzed, num_rows from user_tables;<br />

TABLE_NAME LAST_ANAL NUM_ROWS<br />

------------------------------ --------- ----------<br />

EMP 01-MAY-05 14<br />

GTT1 01-MAY-05 38<br />

GTT2 01-MAY-05 0<br />

Notice that the ON COMMIT PRESERVE rows table has accurate statistics, but the ON COMMIT<br />

DELETE ROWS does not. DBMS_STATS commits, <strong>and</strong> that wipes out any information in that table.<br />

Do note, however, that GTT2 does now have statistics, which in itself is a bad thing, because the<br />

statistics are very much incorrect! It is doubtful the table will have 0 rows in it at runtime. So, if<br />

you use this approach, be aware of two things:<br />

• Make sure to populate your global temporary tables with representative data in the<br />

session that gathers the statistics. If not, they will appear empty to DBMS_STATS.<br />

• If you have ON COMMIT DELETE ROWS global temporary tables, this approach should not<br />

be used, as you will definitely gather inappropriate values.<br />

The second technique that works with ON COMMIT PRESERVE ROWS global temporary tables<br />

is to use GATHER_TABLE_STATS directly on the table. You would populate the global temporary<br />

table as we just did, <strong>and</strong> then execute GATHER_TABLE_STATS on that global temporary table.<br />

Note that just as before, this does not work for ON COMMIT DELETE ROWS global temporary tables,<br />

as the same issues as just described would come into play.<br />

The last technique using DBMS_STATS uses a manual process to populate the data dictionary<br />

with representative statistics for our temporary tables. For example, if on average the<br />

number of rows in the temporary table will be 500, the average row size will be 100 bytes,<br />

<strong>and</strong> the number of blocks will be 7, we could simply use the following:<br />

ops$tkyte@ORA10G> create global temporary table t ( x int, y varchar2(100) );<br />

Table created.<br />

ops$tkyte@ORA10G> begin<br />

2 dbms_stats.set_table_stats( ownname => USER,<br />

3 tabname => 'T',<br />

4 numrows => 500,<br />

5 numblks => 7,<br />

6 avgrlen => 100 );<br />

7 end;

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!