21
101 Ways to get SQL Execution Plan. What is the best option to use? By: Paul Guerin (Originenergy), Serge Stadnichenko (Originenergy), Konrad Dear (Telstra), Yury Velikanov (Pythian), & All of you

101 Ways to get SQL Execution Plan. What is the best option to use?

  • Upload
    ping

  • View
    30

  • Download
    0

Embed Size (px)

DESCRIPTION

101 Ways to get SQL Execution Plan. What is the best option to use?. By: Paul Guerin (Originenergy) , Serge Stadnichenko (Originenergy) , Konrad Dear (Telstra) , Yury Velikanov (Pythian) , & All of you. Introductions. Typical responses to poor performance: - PowerPoint PPT Presentation

Citation preview

Page 1: 101 Ways to get SQL Execution Plan.  What is the best option to use?

101 Ways to get SQL Execution Plan. What is the best option to use?

By:

Paul Guerin (Originenergy),

Serge Stadnichenko (Originenergy),

Konrad Dear (Telstra),

Yury Velikanov (Pythian),

& All of you

Page 2: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Introductions

Typical responses to poor performance:

"We need to buy faster hardware!!!""Someone has been dropping indexes!!!""We need to gather stats on the whole database every 5 minutes!!!""Lets create more materialised views!!!“"We develop the application for optimal performance!!!“"Lets use partitioning option!!!""Lets use parllel option!!!"

Inefficient execution plans lead to poor performance and poor scalability....

Few words about - "What is an execution plan?“

Page 3: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans

> AUTOTRACE (SQL*Plus)> EXPLAN PLAN FOR & DBMS_XPLAN> SQL TRACE aka event 10046> event 10053> Tanel's Dtrace method> V$SQL_PLAN & DBMS_XPLAN.DISPLAY_CURSOR

> SQLT (SQLTXPLAIN) tool from Oracle Support

Page 4: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - SET AUTOTRACE – the simplest option

19:38:52 SYSTEM:MEGA> set autotrace helpmefindparametersUsage: SET AUTOT[RACE] {OFF | ON | TRACE[ONLY]} [EXP[LAIN]]

[STAT[ISTICS]]

SET AUTOTRACE ON<statement>;SET AUTOTRACE OFF

Page 5: 101 Ways to get SQL Execution Plan.  What is the best option to use?

21:14:15 IMTDB:SYSTEM> set autotrace on 21:15:29 IMTDB:SYSTEM> select id from t1 t where n1 > 0; ID ---------- 1 2 3 4 ... 998 999 1000 1000 rows selected. Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=1000 Bytes=7000) 1 0 TABLE ACCESS (FULL) OF 'T1' (Cost=4 Card=1000 Bytes=7000) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 85 consistent gets 0 physical reads 0 redo size 8516 bytes sent via SQL*Net to client 706 bytes received via SQL*Net from client 68 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1000 rows processed 21:17:47 IMTDB:SYSTEM>

Page 6: 101 Ways to get SQL Execution Plan.  What is the best option to use?

21:27:26 SYSTEM:MEGA> set autotrace on 21:27:48 SYSTEM:MEGA> select id from t1 t where n1 > 0; ID ---------- 1 2 3 4 ... 998 999 1000 1000 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 3617692013 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1000 | 7000 | 6 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| T1 | 1000 | 7000 | 6 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("N1">0) Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 85 consistent gets 0 physical reads 0 redo size 11113 bytes sent via SQL*Net to client 1137 bytes received via SQL*Net from client 68 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1000 rows processed 21:28:37 SYSTEM:MEGA>

Page 7: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - SET AUTOTRACE – the simplest option

+ It is most probably the simplest possibe option+ Oracle executes an SQL (true execution plan for given session)+ Oracle executes an SQL (statistics are reflected)

- Oracle executes an SQL (results are reflected, what is thousands rows?)

SET AUTOTRACE TRACEONLY

- Oracle executes an SQL (results are fetched to client side)- Oracle executes an SQL (what if it takes hours before is starts

fetching?)- It doens't provide advantacges that other options have

SET AUTOTRACE ON EXPLAINSET AUTOTRACE ON STATISTICS

To use this feature, you must create a PLAN_TABLE table in your schema and then have the PLUSTRACE role granted to you.

@$ORACLE_HOME/rdbms/admin/utlxplan.sql@$ORACLE_HOME/sqlplus/admin/plustrce.sql

Page 8: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - EXPLAIN PLAN FOR – plan w/t execution

-- No statement execution, displays predicted plan onlyEXPLAIN PLAN FOR <statement>;SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

Page 9: 101 Ways to get SQL Execution Plan.  What is the best option to use?

21:51:00 IMTDB:SYSTEM> explain plan for select id from t1 t where n1 > 0; Explained. 21:51:04 IMTDB:SYSTEM> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------- -------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1000 | 7000 | 4 | |* 1 | TABLE ACCESS FULL | T1 | 1000 | 7000 | 4 | -------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("T"."N1">0) Note: cpu costing is off 14 rows selected. 21:51:08 IMTDB:SYSTEM>

Page 10: 101 Ways to get SQL Execution Plan.  What is the best option to use?

PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------- Plan hash value: 3739423728 ------------------------------------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | ----------------------------------------------------------------------------------------------------- ------------------- | 0 | SELECT STATEMENT | | 1 | 74 | | 34309 (1)|305:38:23 | | 1 | SORT AGGREGATE | | 1 | 74 | | | | | 2 | NESTED LOOPS SEMI | | 2768 | 200K| | 34309 (1)|305:38:23 | | 3 | NESTED LOOPS | | 2768 | 173K| | 28773 (1)|256:19:22 | |* 4 | HASH JOIN | | 521 | 22924 | | 26777 (1)|238:32:29 | | 5 | VIEW | | 499 | 4491 | | 4139 (1)| 36:52:20 | |* 6 | COUNT STOPKEY | | | | | | | | 7 | VIEW | | 255K| 2243K| | 4139 (1)| 36:52:20 | |* 8 | SORT ORDER BY STOPKEY | | 255K| 4736K| 8048K| 4139 (1)| 36:52:20 | |* 9 | TABLE ACCESS FULL | PATIENT_VISIT | 255K| 4736K| | 1618 (0)| 14:24:50 | |* 10 | HASH JOIN RIGHT SEMI | | 292K| 9M| 6416K| 22638 (1)|201:39:53 | |* 11 | TABLE ACCESS FULL | LAB_RESULT_FILE_UPLOAD | 285K| 3068K| | 8781 (0)| 78:13:30 | |* 12 | TABLE ACCESS FULL | STUDY_INV_PATIENT_VISIT_STAGE | 1545K| 35M| | 10655 (0)| 94:55:11 | |* 13 | TABLE ACCESS BY INDEX ROWID| TEST_RESULT_STAGE | 5 | 100 | | 4 (0)| 00:02:09 | |* 14 | INDEX RANGE SCAN | IDX_TRS_PF04 | 6 | | | 3 (0)| 00:01:37 | |* 15 | TABLE ACCESS BY INDEX ROWID | TEST_ORDER | 7739K| 73M| | 2 (0)| 00:01:05 | |* 16 | INDEX UNIQUE SCAN | TEST_ORDER_PK | 1 | | | 1 (0)| 00:00:33 | ------------------------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("SIPVS"."KIT_BARCODE_ID"="KITS_AVAILABLE"."KIT_BARCODE_ID") 6 - filter(ROWNUM<500) 8 - filter(ROWNUM<500) 9 - filter("FINAL_REPORT_DATE" IS NOT NULL AND "ACTIVE"=10) 10 - access("LRFU"."UPLOAD_ID"="SIPVS"."UPLOAD_ID") 11 - filter("LRFU"."LAB_ID"=10034) 12 - filter("SIPVS"."KIT_BARCODE_ID" IS NOT NULL AND "SIPVS"."ACTIVE"=10) 13 - filter("TRS"."TEST_ORDER_ID" IS NOT NULL) 14 - access("SIPVS"."STDINV_PATIENT_VST_STAGE_NF_ID"="TRS"."STDINV_PATIENT_VST_STAGE_NF_ID" AND "TRS"."RESULT_STATUS"=4 AND "TRS"."ACTIVE"=10) filter("TRS"."ACTIVE"=10) 15 - filter("ACTIVE"=10) 16 - access("TOR"."TEST_ORDER_ID"="TRS"."TEST_ORDER_ID") 40 rows selected.

Page 11: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - EXPLAIN PLAN FOR – plan w/t execution

+ It retrives executiion plan witout an SQL execution+ It shows predicates for each step (access/filer)+ It reflects prallel execution and partitioning related infromation

automagicly+ It gives you some Hints about the execution (Note: cpu costing is off)

- Oracle makes assumptions on bind variables data types (wrong execution plan)

Page 12: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - EXPLAIN PLAN FOR – plan w/t execution

DBMS_XPLAN.DISPLAY( table_name IN VARCHAR2 DEFAULT 'PLAN_TABLE', statement_id IN VARCHAR2 DEFAULT NULL, format IN VARCHAR2 DEFAULT 'TYPICAL', filter_preds IN VARCHAR2 DEFAULT NULL);

format

Controls the level of details for the plan. It accepts four values:

* BASIC: Displays the minimum information in the plan—the operation ID, the operation name and its option.

* TYPICAL: This is the default. Displays the most relevant information in the plan (operation id, name and option, #rows, #bytes and optimizer cost). Pruning, parallel and predicate information are only displayed when applicable. Excludes only PROJECTION, ALIAS and REMOTE SQL information (see below).

* SERIAL: Like TYPICAL except that the parallel information is not displayed, even if the plan executes in parallel.

* ALL: Maximum user level. Includes information displayed with the TYPICAL level with additional information (PROJECTION, ALIAS and information about REMOTE SQL if the operation is distributed).

Page 13: 101 Ways to get SQL Execution Plan.  What is the best option to use?

21:50:30 IMTDB:prodds2> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(null,null,'BASIC')); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------- Plan hash value: 3739423728 ------------------------------------------------------------------------ | Id | Operation | Name | ------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | 1 | SORT AGGREGATE | | | 2 | NESTED LOOPS SEMI | | | 3 | NESTED LOOPS | | | 4 | HASH JOIN | | | 5 | VIEW | | | 6 | COUNT STOPKEY | | | 7 | VIEW | | | 8 | SORT ORDER BY STOPKEY | | | 9 | TABLE ACCESS FULL | PATIENT_VISIT | | 10 | HASH JOIN RIGHT SEMI | | | 11 | TABLE ACCESS FULL | LAB_RESULT_FILE_UPLOAD | | 12 | TABLE ACCESS FULL | STUDY_INV_PATIENT_VISIT_STAGE | | 13 | TABLE ACCESS BY INDEX ROWID| TEST_RESULT_STAGE | | 14 | INDEX RANGE SCAN | IDX_TRS_PF04 | | 15 | TABLE ACCESS BY INDEX ROWID | TEST_ORDER | | 16 | INDEX UNIQUE SCAN | TEST_ORDER_PK | ------------------------------------------------------------------------ 23 rows selected. 22:27:03 IMTDB:prodds2>

Page 14: 101 Ways to get SQL Execution Plan.  What is the best option to use?

22:29:16 IMTDB:prodds2> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(null,null,'ALL')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------ - Plan hash value: 3739423728 ------------------------------------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 74 | | 34309 (1)|305:38:23 | | 1 | SORT AGGREGATE | | 1 | 74 | | | | | 2 | NESTED LOOPS SEMI | | 2768 | 200K| | 34309 (1)|305:38:23 | | 3 | NESTED LOOPS | | 2768 | 173K| | 28773 (1)|256:19:22 | |* 4 | HASH JOIN | | 521 | 22924 | | 26777 (1)|238:32:29 | | 5 | VIEW | | 499 | 4491 | | 4139 (1)| 36:52:20 | |* 6 | COUNT STOPKEY | | | | | | | | 7 | VIEW | | 255K| 2243K| | 4139 (1)| 36:52:20 | |* 8 | SORT ORDER BY STOPKEY | | 255K| 4736K| 8048K| 4139 (1)| 36:52:20 | |* 9 | TABLE ACCESS FULL | PATIENT_VISIT | 255K| 4736K| | 1618 (0)| 14:24:50 | |* 10 | HASH JOIN RIGHT SEMI | | 292K| 9M| 6416K| 22638 (1)|201:39:53 | |* 11 | TABLE ACCESS FULL | LAB_RESULT_FILE_UPLOAD | 285K| 3068K| | 8781 (0)| 78:13:30 | |* 12 | TABLE ACCESS FULL | STUDY_INV_PATIENT_VISIT_STAGE | 1545K| 35M| | 10655 (0)| 94:55:11 | |* 13 | TABLE ACCESS BY INDEX ROWID| TEST_RESULT_STAGE | 5 | 100 | | 4 (0)| 00:02:09 | |* 14 | INDEX RANGE SCAN | IDX_TRS_PF04 | 6 | | | 3 (0)| 00:01:37 | |* 15 | TABLE ACCESS BY INDEX ROWID | TEST_ORDER | 7739K| 73M| | 2 (0)| 00:01:05 | |* 16 | INDEX UNIQUE SCAN | TEST_ORDER_PK | 1 | | | 1 (0)| 00:00:33 | ------------------------------------------------------------------------------------------------------------------------ Query Block Name / Object Alias (identified by operation id): ------------------------------------------------------------- 1 - SEL$F2CA64D4 5 - SEL$2 / KITS_AVAILABLE@SEL$1 6 - SEL$2 7 - SEL$3 / from$_subquery$_004@SEL$2 8 - SEL$3 9 - SEL$3 / PATIENT_VISIT@SEL$3 11 - SEL$F2CA64D4 / LRFU@SEL$5 12 - SEL$F2CA64D4 / SIPVS@SEL$1 13 - SEL$F2CA64D4 / TRS@SEL$1 14 - SEL$F2CA64D4 / TRS@SEL$1 15 - SEL$F2CA64D4 / TOR@SEL$4 16 - SEL$F2CA64D4 / TOR@SEL$4 Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("SIPVS"."KIT_BARCODE_ID"="KITS_AVAILABLE"."KIT_BARCODE_ID") 6 - filter(ROWNUM<500) 8 - filter(ROWNUM<500) 9 - filter("FINAL_REPORT_DATE" IS NOT NULL AND "ACTIVE"=10) 10 - access("LRFU"."UPLOAD_ID"="SIPVS"."UPLOAD_ID") 11 - filter("LRFU"."LAB_ID"=10034) 12 - filter("SIPVS"."KIT_BARCODE_ID" IS NOT NULL AND "SIPVS"."ACTIVE"=10) 13 - filter("TRS"."TEST_ORDER_ID" IS NOT NULL) 14 - access("SIPVS"."STDINV_PATIENT_VST_STAGE_NF_ID"="TRS"."STDINV_PATIENT_VST_STAGE_NF_ID" AND "TRS"."RESULT_STATUS"=4 AND "TRS"."ACTIVE"=10) filter("TRS"."ACTIVE"=10) 15 - filter("ACTIVE"=10) 16 - access("TOR"."TEST_ORDER_ID"="TRS"."TEST_ORDER_ID") Column Projection Information (identified by operation id): ----------------------------------------------------------- 1 - (#keys=0) COUNT(*)[22] 2 - (#keys=0) 3 - (#keys=0) "TRS"."TEST_ORDER_ID"[NUMBER,22] 4 - (#keys=1) "SIPVS"."STDINV_PATIENT_VST_STAGE_NF_ID"[NUMBER,22] 5 - "KITS_AVAILABLE"."KIT_BARCODE_ID"[VARCHAR2,30] 6 - "KIT_BARCODE_ID"[VARCHAR2,30] 7 - "KIT_BARCODE_ID"[VARCHAR2,30] 8 - (#keys=1) INTERNAL_FUNCTION("FINAL_REPORT_DATE")[7], "KIT_BARCODE_ID"[VARCHAR2,30] 9 - "KIT_BARCODE_ID"[VARCHAR2,30], "FINAL_REPORT_DATE"[DATE,7]

Page 15: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - SET AUTOTRACE – might lie !

REF: Jonathan Lewis

http://jonathanlewis.wordpress.com/testing-autotrace/

set autotrace traceonly explain – doens’t execute an SQL

Page 16: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Konrad

> SQL TRACE aka event 10046

> event 10053

> Tanel's Dtrace method

Page 17: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - v$sql_plan

Determine the session and cursorv$session, v$sql: hash_value, address, child_number (9i)

sql_id, child_number (11g)

Session activity gives clues to what is in the execution plan…

v$session_event: db file sequential read, db file scattered readv$session_wait:v$session_longops: Table Scan

Page 18: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - v$sql_plan

Actual execution plan (9i)

truncate table plan_table;

-- Following is equivalent to EXPLAIN PLAN FOR <statement>insert into plan_table (statement_id, timestamp, OPERATION, OPTIONS, OBJECT_NODE,

OBJECT_OWNER, OBJECT_NAME, OPTIMIZER, ID, PARENT_ID, POSITION, SEARCH_COLUMNS, COST, CARDINALITY, BYTES, OTHER_TAG, PARTITION_START, PARTITION_STOP, PARTITION_ID, OTHER, DISTRIBUTION, CPU_COST, IO_COST, TEMP_SPACE, ACCESS_PREDICATES, FILTER_PREDICATES)

select 0, sysdate, OPERATION, OPTIONS, OBJECT_NODE, OBJECT_OWNER, OBJECT_NAME, OPTIMIZER, ID, PARENT_ID, POSITION, SEARCH_COLUMNS, COST, CARDINALITY, BYTES,

OTHER_TAG, PARTITION_START, PARTITION_STOP, PARTITION_ID, OTHER, DISTRIBUTION, CPU_COST, IO_COST, TEMP_SPACE, ACCESS_PREDICATES, FILTER_PREDICATES

from v$sql_planwhere hash_value=&hsh and address='&add' and child_number=&chld;

-- Displays the actual plan instead of the predicted planselect * from table(dbms_xplan.display);

Page 19: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - v$sql_plan

Actual execution plan (10g/11g)

-- execution plan for last cursor of sessionSELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR);

-- execution plan for a cached cursor (need sql_id + child_number from v$sql)SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR('<sql_id>',<child#>));

-- execution plan for an AWR cursor (need sql_id from DBA_HIST_SQLTEXT)SELECT * FROM table(DBMS_XPLAN.DISPLAY_AWR('<sql_id>'));

-- Plan related dynamic viewsV$SQL_PLANV$SQL_PLAN_MONITOR Plan level monitoring statistics.V$SQL_BIND_CAPTURE Bind variables used for a cursor.V$SQL_BIND_DATA As above, except for current session.

Page 20: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans

11g features:

DBMS_SQLTUNE.REPORT_SQL_MONITOR();Create a report that can include explain plan and binds.

SQL Plan BaselinesStorage of past plans that are considered efficient.

Page 21: 101 Ways to get SQL Execution Plan.  What is the best option to use?

Execution plans - SQLT (SQLTXPLAIN) tool from Oracle Support

DEMO

SQLT (SQLTXPLAIN) –

Tool that helps to diagnose SQL statements performing poorly [ID 215187.1]

+ It is most complete and comprehansive option+ Support 9.2.0.1 to 11.2.0.1 RDBMS versions+ Can use many different sources as input

- Needs additional instaltion in the production DB+ Install in totaly isolated schema (SQLTXPLAIN)- A report generating process is relativly complex

(as application owner with additional privileges, multiple stages)- Sometimes generating process is resources intensive