Oracle-DB: Find SQLs where expected parallel DML or direct load does not work
If you try to use parallel DML or direct load in SQL statements by placing the appropiate optimizer hints (PARALLEL, APPEND etc.),
there might be several reasons why the DB ignores them.
For example, if you want to execute DML in parallel you need to enable the session to do this before by executing
The free performance analysis tool Panorama offers a way to scan your entire database for SQLs where parallel DML or direct load should have been used but in reality is not.
Use the shown selection from menu "Dragnet investigation" (point 2.2.12) to execute this check and find SQLs that are not executed as expected. The result is sorted by the time this SQLs took to execute. The link in column "sql id" allows you to dig deeper in the details of the found SQL statement.
Precondition is licensing of Oracle Diagnostics Pack or the use of Panorama-Sampler as an alternative. Without using "Panorama" you can also execute the following SQL manually. You should have licensed the Oracle Diagnostics Pack and replace the DBID with the numeric value of your DB ID.
For example, if you want to execute DML in parallel you need to enable the session to do this before by executing
ALTER SESSION ENABLE PARALLEL DML;. There are lots of similar pitfalls that may prevent the DB from using the expected execution path.
The free performance analysis tool Panorama offers a way to scan your entire database for SQLs where parallel DML or direct load should have been used but in reality is not.
Use the shown selection from menu "Dragnet investigation" (point 2.2.12) to execute this check and find SQLs that are not executed as expected. The result is sorted by the time this SQLs took to execute. The link in column "sql id" allows you to dig deeper in the details of the found SQL statement.
Precondition is licensing of Oracle Diagnostics Pack or the use of Panorama-Sampler as an alternative. Without using "Panorama" you can also execute the following SQL manually. You should have licensed the Oracle Diagnostics Pack and replace the DBID with the numeric value of your DB ID.
WITH Plans AS (SELECT /*+ NO_MERGE MATERIALIZE */ SQL_ID, Plan_Hash_Value, PDML_Reason, IDL_Reason FROM (SELECT SQL_ID, Plan_Hash_Value, EXTRACTVALUE(XMLTYPE(Other_XML), '/*/info[@type = "pdml_reason"]') PDML_Reason, EXTRACTVALUE(XMLTYPE(Other_XML), '/*/info[@type = "idl_reason"]') IDL_Reason FROM gv$SQL_Plan WHERE Other_XML LIKE '%pdml_reason%' OR Other_XML LIKE '%idl_reason%' UNION ALL SELECT SQL_ID, Plan_Hash_Value, EXTRACTVALUE(XMLTYPE(Other_XML), '/*/info[@type = "pdml_reason"]') pdml_reason, EXTRACTVALUE(XMLTYPE(Other_XML), '/*/info[@type = "idl_reason"]') IDL_Reason FROM DBA_Hist_SQL_Plan WHERE DBID = :DBID /* do not count multiple times for multiple different DBIDs/ConIDs */ AND Other_XML LIKE '%pdml_reason%' OR Other_XML LIKE '%idl_reason%' ) WHERE PDML_Reason IS NOT NULL OR IDL_Reason IS NOT NULL GROUP BY SQL_ID, Plan_Hash_Value, PDML_Reason, IDL_Reason /* DISTINCT */ ), Min_Ash AS (SELECT /*+ NO_MERGE MATERIALIZE */ Inst_ID, MIN(Sample_Time) Min_Sample_Time FROM gv$Active_Session_History GROUP BY Inst_ID), ASH AS (SELECT /*+ NO_MERGE MATERIALIZE */ SQL_ID, SQL_Plan_Hash_Value, User_ID, SUM(Elapsed_Secs) Elapsed_Secs FROM (SELECT /*+ NO_MERGE */ SQL_ID, SQL_Plan_Hash_Value, User_ID, COUNT(*) Elapsed_Secs FROM gv$Active_Session_History GROUP BY SQL_ID, SQL_Plan_Hash_Value, User_ID UNION ALL SELECT /*+ NO_MERGE */ SQL_ID, SQL_Plan_Hash_Value, User_ID, COUNT(*) * 10 Elapsed_Secs FROM DBA_Hist_Active_Sess_History h JOIN Min_Ash ma ON ma.Inst_ID = h.Instance_Number WHERE Sample_Time > SYSDATE - :Considered_Days_Back AND Sample_Time < ma.Min_Sample_Time AND DBID = :DBID /* do not count multiple times for multiple different DBIDs/ConIDs */ GROUP BY SQL_ID, SQL_Plan_Hash_Value, User_ID ) WHERE User_ID NOT IN (SELECT /*+ NO_MERGE */ User_ID FROM All_Users WHERE Oracle_Maintained = 'Y') GROUP BY SQL_ID, SQL_Plan_Hash_Value, User_ID ) SELECT /*+ LEADING(p) USE_HASH(ash) */ p.SQL_ID, p.Plan_Hash_Value, p.PDML_Reason, p.IDL_Reason, u.UserName, SUM(ash.Elapsed_Secs) Elapsed_Secs FROM Plans p JOIN Ash ON ash.SQL_ID = p.SQL_ID AND ash.SQL_Plan_Hash_Value = p.Plan_Hash_Value LEFT OUTER JOIN All_Users u ON u.User_ID = ash.User_ID GROUP BY p.SQL_ID, p.Plan_Hash_Value, p.PDML_Reason, p.IDL_Reason, u.UserName ORDER BY SUM(ash.Elapsed_Secs) DESC
Comments
Post a Comment