In my previous posts here and here, I have shown how to use the GATHER_PLAN_STATISTICS Hint to collect additional information. But what if you can't modify the SELECT query statement ?
You could set STATISTICS_LEVEL='ALL' at the session, run the query and then reset STATISTICS_LEVEL to the default 'TYPICAL'
SQL> alter session set tracefile_identifier='H2'; Session altered. SQL> alter session set statistics_level='ALL'; Session altered. SQL> exec DBMS_SESSION.SET_SQL_TRACE(sql_trace=>TRUE); -- just to get the SQL_ID in the trace file PL/SQL procedure successfully completed. SQL> SQL> select 2 d.department_id, d.department_name, e.first_name, e.last_name 3 from hr.departments d join hr.employees e 4 on d.department_id=e.department_id 5 order by 1,2,4,3 6 / .... .... .... 106 rows selected. SQL> SQL> exec DBMS_SESSION.SET_SQL_TRACE(sql_trace=>FALSE); PL/SQL procedure successfully completed. SQL> QL> select * from table(dbms_xplan.display_cursor('4aa2k5b98ybfr',format=>'ALLSTATS LAST')); -- SQL_ID identified from the trace file PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ SQL_ID 4aa2k5b98ybfr, child number 0 ------------------------------------- select d.department_id, d.department_name, e.first_name, e.last_name from hr.departments d join hr.employees e on d.department_id=e.department_id order by 1,2,4,3 Plan hash value: 2209899241 ------------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem | ------------------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 106 |00:00:00.10 | 10 | 14 | | | | | 1 | SORT ORDER BY | | 1 | 106 | 106 |00:00:00.10 | 10 | 14 | 11264 | 11264 |10240 (0)| | 2 | MERGE JOIN | | 1 | 106 | 106 |00:00:00.10 | 10 | 14 | | | | | 3 | TABLE ACCESS BY INDEX ROWID| DEPARTMENTS | 1 | 27 | 12 |00:00:00.03 | 2 | 2 | | | | | 4 | INDEX FULL SCAN | DEPT_ID_PK | 1 | 27 | 12 |00:00:00.03 | 1 | 1 | | | | |* 5 | SORT JOIN | | 12 | 107 | 106 |00:00:00.06 | 8 | 12 | 9216 | 9216 | 8192 (0)| | 6 | VIEW | index$_join$_002 | 1 | 107 | 106 |00:00:00.06 | 8 | 12 | | | | |* 7 | HASH JOIN | | 1 | | 106 |00:00:00.06 | 8 | 12 | 1610K| 1610K| 1658K (0)| | 8 | INDEX FAST FULL SCAN | EMP_DEPARTMENT_IX | 1 | 107 | 106 |00:00:00.06 | 4 | 6 | | | | | 9 | INDEX FAST FULL SCAN | EMP_NAME_IX | 1 | 107 | 107 |00:00:00.01 | 4 | 6 | | | | ------------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - access("D"."DEPARTMENT_ID"="E"."DEPARTMENT_ID") filter("D"."DEPARTMENT_ID"="E"."DEPARTMENT_ID") 7 - access(ROWID=ROWID) 30 rows selected. SQL>
Thus, I was able to get similar execution statistics without the Hint if I set STATISTICS_LEVEL='ALL'.
(Note : The top level operation here is a MERGE JOIN while that in the first example of the first post of this series on 27-January-22 was a HASH JOIN. The result here is 106 rows, not the 108 rows in the first example. The first example was in an HR schema in another database -- e.g. you would see DEPARTMENT_ID=280 'New Department' and Employee 'HEMANT CHITALE' in that listing. These are two different HR schemas where I have modified some of the data. Thus, you'll see a difference in the Execution Plan as well between the first example and this one. although the query is similar -- because the databases, patch levels, possibly optimizer parameters, schema and data are different.)
Even a slight difference in data or parameters or patch levels can result in different execution plans !
No comments:
Post a Comment