Tuesday, December 1, 2009

Global Temporary Table performance issue

Based on Oracle SR responses and vendor’s recommendation I ran few test cases to analyze global temporary table performance issues






Test Case 1:



Step 1: Create Global Temporary Table PRADIPTA.PATIENT_INTERFACE_TEMP with primary key



SQL > CREATE GLOBAL TEMPORARY TABLE PRADIPTA.PATIENT_INTERFACE_TEMP

( …………………

……………………

) ON COMMIT PRESERVE ROWS NOCACHE ENABLE ROW MOVEMENT;



SQL > ALTER TABLE PRADIPTA.PATIENT_INTERFACE_TEMP ADD (

CONSTRAINT PK_PATIENT_INTERFACE_TEMP

PRIMARY KEY

(PATIENT_INT_KEY));



Step 2: Checking table statistics information





SQL> select table_name,num_rows,last_analyzed from dba_tab_statistics where table_name='PATIENT_INTERFACE_TEMP' and owner='PRADIPTA';



TABLE_NAME NUM_ROWS LAST_ANALYZED

------------------------------ ---------- -------------

PATIENT_INTERFACE_TEMP



Step 3: Gathering Status on PRADIPTA.PATIENT_INTERFACE_TEMP as ORACLE MAINTANANCE windows does every night



SQL > begin

dbms_stats.gather_table_stats(ownname => 'PRADIPTA', tabname => 'PATIENT_INTERFACE_TEMP', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt=>'FOR ALL COLUMNS SIZE AUTO');

end;

/



Step4: Checking table statistics information after Gather stats



TABLE_NAME NUM_ROWS LAST_ANALYZED

------------------------------ ---------- -------------

PATIENT_INTERFACE_TEMP 0 16-FEB-12



Step 5: Run the process



Process 1: Insert into PRADIPTA.PATIENT_INTERFACE_TEMP;

105695 rows created.

Elapsed: 00:00:01.81



Process 2: Select from PRADIPTA.PATIENT_INTERFACE_TEMP using join to DD.PATIENT_DIM

105674 rows created

Elapsed: 3 – 4 hours



Test Case 2:



Step 1: Delete table statistics on PRADIPTA.PATIENT_INTERFACE_TEMP



SQL > BEGIN

dbms_stats.delete_table_stats(ownname => 'PRADIPTA', tabname => 'PATIENT_INTERFACE_TEMP');

END;

/



Step 2: Checking table statistics information after Gather stats



TABLE_NAME NUM_ROWS LAST_ANALYZED

------------------------------ ---------- -------------

PATIENT_INTERFACE_TEMP



Step 3: Run the process



Process 1: Insert into PRADIPTA.PATIENT_INTERFACE_TEMP;

105695 rows created.

Elapsed: 00:00:01.81 (2 seconds)



Process 2: Select from PRADIPTA.PATIENT_INTERFACE_TEMP using join to DD.PATIENT_DIM

105674 rows created

Elapsed: 00:01:36.91 (1 mins 36 seconds)



Test Case 3:



Step 1: Lock table statistics on PRADIPTA.PATIENT_INTERFACE_TEMP so ORACLE MAINTANANCE window will not gather stats.



SQL > BEGIN

dbms_stats.unlock_table_stats(ownname => 'PRADIPTA', tabname => 'PATIENT_INTERFACE_TEMP');

END;



/

Step 2: Checking table statistics information after Gather stats



TABLE_NAME NUM_ROWS LAST_ANALYZED

------------------------------ ---------- -------------

PATIENT_INTERFACE_TEMP





Step 3: Run the process



Process 1: Insert into PRADIPTA.PATIENT_INTERFACE_TEMP;

105695 rows created.

Elapsed: 00:00:01.81 (2 seconds)



Process 2: Select from PRADIPTA.PATIENT_INTERFACE_TEMP using join to DD.PATIENT_DIM

105674 rows created

Elapsed: 00:01:36.91 (1 mins 36 seconds)







Conclusion:



Oracle (nightly maintenance window job) is gathering statistics on global temporary table, which eventually causing the PATIENT matching performance issue.



Question 1: Why Oracle is gathering status on GTT (Global Temporary Table)?



Question 2: Are Oracle gather stats parameters efficient enough to analyze correct statistics for our application ??