• Save
Oracle Query Tuning Tips - Get it Right the First Time
Upcoming SlideShare
Loading in...5
×
 

Oracle Query Tuning Tips - Get it Right the First Time

on

  • 400 views

Whether you are a developer or DBA, this presentation will outline a method for determining the best approach for tuning a query every time by utilizing response time analysis and SQL Diagramming ...

Whether you are a developer or DBA, this presentation will outline a method for determining the best approach for tuning a query every time by utilizing response time analysis and SQL Diagramming techniques. Regardless of the complexity of the statement or database platform being utilized (this method works on all), this quick and systematic approach will lead you down the correct
tuning path with no guessing. If you are a beginner or expert, this approach will save you countless hours tuning a query.

Statistics

Views

Total Views
400
Views on SlideShare
400
Embed Views
0

Actions

Likes
1
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Oracle Query Tuning Tips - Get it Right the First Time Oracle Query Tuning Tips - Get it Right the First Time Presentation Transcript

  • SQL Query Tuning Tips for OracleGet it Right the First TimeDean RichardsLead DBA, Confio Software2/21/2013 1
  • 2/21/2013 Confidential - Internal Use Only 2Who Am I?• 20+ Years in Oracle & SQL Server– DBA and Developer– Worked for Oracle SPG• Lead DBA for Confio Software– DeanRichards@confio.com– Makers of Ignite8 Response Time Analysis Tools– http://www.ignitefree.com – only free RTA Tool• Specialize in Performance Tuning
  • 2/21/2013 3Agenda• Introduction• Which Query Should I Tune?• Query Plans• SQL Diagramming– Who registered yesterday for Tuning Class– Check order status
  • 2/21/2013 Confidential - Internal Use Only 4Why Focus on Queries• Most Applications– Read and Write data to/from database– Simple manipulation of data– Deal with smaller amounts of data• Most Databases– Examine larger amounts of data, return a little– Inefficiencies quickly become bottleneck• Why do SQL tuning?– Tuning SQL - “Gives the most bang for your buck”– Changes to SQL are Safer– ~85% of performance issues are SQL related
  • 2/21/2013 Confidential - Internal Use Only 5Who Should Tune• Developers?– Developing applications is very difficult– Typically focused on functionality– Not much time left to tune SQL– Do not get enough practice– SQL runs differently in Production than Dev/Test• DBA?– Do not know the code like developers do– Focus on “Keep the Lights On”– Very complex environment• Need a team approach– But also need someone to lead the effort
  • 2/21/2013 Confidential - Internal Use Only 6Which SQL• User / Batch Job Complaints• Queries Performing Most I/O (LIO, PIO)• Queries Consuming CPU• Queries Doing Full Table Scans• Known Poorly Performing SQL• Tracing a Session / Process• Highest Response Times (Ignite for Oracle)select sql_text, elapsed_time, cpu_time, executions,sql_id, hash_value, last_active_time,plan_hash_value, program_id, module, actionfrom v$sqlorder by elapsed_time/
  • 2/21/2013 Confidential - Internal Use Only 7SQL Wait States Understand the total time a Query spends in Database Measure time while Query executes SQL Server helps by providing Wait TypesFocus on Response Time
  • 2/21/2013 Confidential - Internal Use Only 8Oracle Wait InterfaceV$SQLSQL_IDSQL_FULLTEXTV$SESSIONSIDUSERNAMESQL_IDPROGRAMMODULEACTIONPLAN_HASH_VALUEROW_WAIT_OBJ#V$SQLAREASQL_IDEXECUTIONSPARSE_CALLSBUFFER_GETSDISK_READSV$SESSION_WAITSIDEVENTP1, P1RAW, P2, P2RAW, P3, P3RAWSTATE (WAITING, WAITED…)• Oracle 10g added this info to V$SESSIONV$SQL_PLANSQL_IDPLAN_HASH_VALUEDBA_OBJECTSOBJECT_IDOBJECT_NAMEOBJECT_TYPE
  • 2/21/2013 Confidential - Internal Use Only 9Oracle Wait InterfaceSELECT s.sql_id, sql.sql_text, sql.plan_hash_value,DECODE(s.state, WAITING, s.event, CPU/LogicalIO) waitevent,s.p1, s.p2, s.p3FROM v$session s, v$sql sqlWHERE s.sql_id = sql.sql_idAND s.sql_address = sql.addressAND program = ‘…’ AND s.sid = …AND <whatever else you know>
  • 2/21/2013 Confidential - Internal Use Only 10SQL Plan• EXPLAIN PLAN– Estimated execution plan– Can be wrong for many reasons– What most tools show you• V$SQL_PLAN (Oracle 9i+)– Real execution plan– Use DBMS_XPLAN for display• Confio Ignite for Oracle– Gathers real plan– Shows it historically
  • 2/21/2013 Confidential - Internal Use Only 11DBMS_XPLANselect * from table (dbms_xplan.display_cursor(‘&SQLID’,ChildNo));PLAN_TABLE_OUTPUT--------------------------------------------------------------------------------SQL_ID f7jqysdfu2f2s, child number 0-------------------------------------update emp set hire_date = to_date(:1) where id=:2Plan hash value: 1494045816---------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |---------------------------------------------------------------------------| 0 | UPDATE STATEMENT | | | | 3025 (100)| || 1 | UPDATE | EMP | | | | ||* 2 | TABLE ACCESS FULL| EMP | 122 | 2684 | 3025 (1)| 00:00:37 |---------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------2 - filter("ID"=3247)
  • 2/21/2013 Confidential - Internal Use Only 12All Plans Not EqualSELECT company, attribute FROM data_out WHERE segment = :B1• Wait Time – 100% on “db file scattered read”• Plan from EXPLAIN PLAN• Plan from V$SQL_PLAN using DBMS_XPLAN
  • 2/21/2013 Confidential - Internal Use Only 13Bind Values• V$SQL_BIND_CAPTURE– STATISTICS_LEVEL = TYPICAL or ALL– Collected at 15 minute intervalsSELECT name, position, datatype_string, value_stringFROM v$sql_bind_captureWHERE sql_id = 15uughacxfh13;NAME POSITION DATATYPE_STRING VALUE_STRING----- ---------- --------------- ------------:B1 1 BINARY_DOUBLE 189• Bind Values also provided by tracing– Level 4 – bind values– Level 8 – wait information– Level 12 – bind values and wait information
  • 2/21/2013 Confidential - Internal Use Only 14Case Studies• SQL Diagramming• Case Study 1– Who registered for Tuning Class yesterday• Case Study 2– Check order status
  • 2/21/2013 Confidential - Internal Use Only 15Case Study 1• Who registered yesterday for SQL TuningSELECT s.fname, s.lname, r.signup_dateFROM student sINNER JOIN registration r ON s.student_id = r.student_idINNER JOIN class c ON r.class_id = c.class_idWHERE c.name = SQL TUNINGAND r.signup_date BETWEEN :1 AND :2AND r.cancelled = N• Execution Stats – 12,634 Logical Reads
  • 2/21/2013 Confidential - Internal Use Only 16Database Diagram
  • 2/21/2013 Confidential - Internal Use Only 17Execution Plan----------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |----------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 7 | 819 | 3173 (5)| 00:00:39 ||* 1 | FILTER | | | | | || 2 | NESTED LOOPS | | | | | || 3 | NESTED LOOPS | | 7 | 819 | 3173 (5)| 00:00:39 ||* 4 | HASH JOIN | | 7 | 448 | 3166 (5)| 00:00:38 ||* 5 | TABLE ACCESS FULL | CLASS | 1 | 45 | 22 (0)| 00:00:01 ||* 6 | TABLE ACCESS FULL | REGISTRATION | 8334 | 154K| 3144 (5)| 00:00:38 ||* 7 | INDEX UNIQUE SCAN | PK_STUDENT | 1 | | 0 (0)| 00:00:01 || 8 | TABLE ACCESS BY INDEX ROWID| STUDENT | 1 | 53 | 1 (0)| 00:00:01 |----------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------1 - filter(TRUNC(SYSDATE@!-1)<=TRUNC(SYSDATE@!))4 - access("R"."CLASS_ID"="C"."CLASS_ID")5 - filter("C"."NAME"=SQL TUNING)6 - filter("R"."SIGNUP_DATE">=TRUNC(SYSDATE@!-1) AND "R"."CANCELLED"=N AND"R"."SIGNUP_DATE"<=TRUNC(SYSDATE@!))7 - access("S"."STUDENT_ID"="R"."STUDENT_ID")
  • 2/21/2013 Confidential - Internal Use Only 18SQL Diagrammingregistrationstudent class51301.03.001select count(1) from registration where cancelled = Nand signup_date between 2012-12-05 00:00 and 2012-12-06 00:0054,554 / 1,639,186 = 0.03select count(1) from class where name = SQL TUNING2 / 1,267 = .001• Great Book - “SQL Tuning” by Dan Tow– Teaches SQL Diagramming– http://www.singingsql.com
  • 2/21/2013 Confidential - Internal Use Only 19New Execution Plan• Execution Stats – 11,168 Logical Reads• Why does a Full Table Scan still occur on REGISTRATION?------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 7 | 819 | 3153 (5)| 00:00:38 ||* 1 | FILTER | | | | | || 2 | NESTED LOOPS | | | | | || 3 | NESTED LOOPS | | 7 | 819 | 3153 (5)| 00:00:38 ||* 4 | HASH JOIN | | 7 | 448 | 3146 (5)| 00:00:38 || 5 | TABLE ACCESS BY INDEX ROWID| CLASS | 1 | 45 | 2 (0)| 00:00:01 ||* 6 | INDEX RANGE SCAN | CL_NAME | 1 | | 1 (0)| 00:00:01 ||* 7 | TABLE ACCESS FULL | REGISTRATION | 8334 | 154K| 3144 (5)| 00:00:38 ||* 8 | INDEX UNIQUE SCAN | PK_STUDENT | 1 | | 0 (0)| 00:00:01 || 9 | TABLE ACCESS BY INDEX ROWID | STUDENT | 1 | 53 | 1 (0)| 00:00:01 |------------------------------------------------------------------------------------------------CREATE INDEX cl_name ON class(name)
  • 2/21/2013 Confidential - Internal Use Only 20Database Diagram
  • 2/21/2013 Confidential - Internal Use Only 21New Execution PlanCREATE INDEX reg_alt ON registration(class_id)• Execution Stats – 4,831 Logical Reads------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 7 | 819 | 2415 (1)| 00:00:29 ||* 1 | FILTER | | | | | || 2 | NESTED LOOPS | | | | | || 3 | NESTED LOOPS | | 7 | 819 | 2415 (1)| 00:00:29 || 4 | NESTED LOOPS | | 7 | 448 | 2408 (1)| 00:00:29 || 5 | TABLE ACCESS BY INDEX ROWID| CLASS | 1 | 45 | 2 (0)| 00:00:01 ||* 6 | INDEX RANGE SCAN | CL_NAME | 1 | | 1 (0)| 00:00:01 ||* 7 | TABLE ACCESS BY INDEX ROWID| REGISTRATION | 7 | 133 | 2406 (1)| 00:00:29 ||* 8 | INDEX RANGE SCAN | REG_ALT | 2667 | | 9 (0)| 00:00:01 ||* 9 | INDEX UNIQUE SCAN | PK_STUDENT | 1 | | 0 (0)| 00:00:01 || 10 | TABLE ACCESS BY INDEX ROWID | STUDENT | 1 | 53 | 1 (0)| 00:00:01 |------------------------------------------------------------------------------------------------
  • 2/21/2013 Confidential - Internal Use Only 22Case Study 2• Lookup order status for callerSELECT o.OrderID, c.LastName, p.ProductID, p.Description,sd.ActualShipDate, sd.ShipStatus, sd.ExpectedShipDateFROM Orders oINNER JOIN Item i ON i.OrderID = o.OrderIDINNER JOIN Customer c ON c.CustomerID = o.CustomerIDINNER JOIN ShipmentDetails sd ON sd.ShipmentID = i.ShipmentIDINNER JOIN Product p ON p.ProductID = i.ProductIDINNER JOIN Address a ON a.AddressID = sd.AddressIDWHERE c.LastName LIKE NVL(:1,) || %AND c.FirstName LIKE NVL(:2,) || %AND o.OrderDate >= SYSDATE - 30AND o.OrderStatus <> C• Execution Stats – 73,600 Logical Reads
  • 2/21/2013 Confidential - Internal Use Only 23Case Study 2• Lookup order status for callerSELECT o.OrderID, c.LastName, p.ProductID, p.Description,sd.ActualShipDate, sd.ShipStatus, sd.ExpectedShipDateFROM Orders oINNER JOIN Item i ON i.OrderID = o.OrderIDINNER JOIN Customer c ON c.CustomerID = o.CustomerIDINNER JOIN ShipmentDetails sd ON sd.ShipmentID = i.ShipmentIDINNER JOIN Product p ON p.ProductID = i.ProductIDINNER JOIN Address a ON a.AddressID = sd.AddressIDWHERE c.LastName LIKE SMI%AND c.FirstName LIKE %AND o.OrderDate >= SYSDATE - 30AND o.OrderStatus <> C• Execution Stats – 73,600 Logical Reads
  • 2/21/2013 Confidential - Internal Use Only 24Database Diagram
  • 2/21/2013 Confidential - Internal Use Only 25--------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |--------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 6 | 1164 | 4892 (2)| 00:00:59 || 1 | NESTED LOOPS | | | | | || 2 | NESTED LOOPS | | 6 | 1164 | 4892 (2)| 00:00:59 || 3 | NESTED LOOPS | | 6 | 510 | 4886 (2)| 00:00:59 ||* 4 | HASH JOIN | | 105 | 5460 | 4782 (2)| 00:00:58 ||* 5 | HASH JOIN | | 1320 | 44880 | 4118 (2)| 00:00:50 ||* 6 | TABLE ACCESS FULL | SHIPMENTDETAILS | 304 | 6080 | 1070 (2)| 00:00:13 || 7 | TABLE ACCESS FULL | ITEM | 3588K| 47M| 3036 (1)| 00:00:37 ||* 8 | TABLE ACCESS FULL | ORDERS | 54903 | 965K| 663 (3)| 00:00:08 ||* 9 | TABLE ACCESS BY INDEX ROWID| CUSTOMER | 1 | 33 | 1 (0)| 00:00:01 ||* 10 | INDEX UNIQUE SCAN | PK_CUSTOMER | 1 | | 0 (0)| 00:00:01 ||* 11 | INDEX UNIQUE SCAN | PK_PRODUCT | 1 | | 0 (0)| 00:00:01 || 12 | TABLE ACCESS BY INDEX ROWID | PRODUCT | 1 | 109 | 1 (0)| 00:00:01 |--------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------4 - access("I"."ORDERID"="O"."ORDERID")5 - access("SD"."SHIPMENTID"="I"."SHIPMENTID")6 - filter("SD"."SHIPSTATUS"<>C)8 - filter("O"."ORDERDATE">=SYSDATE@!-30)9 - filter("C"."LASTNAME" LIKE SMI%)10 - access("C"."CUSTOMERID"="O"."CUSTOMERID")11 - access("P"."PRODUCTID"="I"."PRODUCTID")Execution Plan
  • 2/21/2013 Confidential - Internal Use Only 26SELECT COUNT(1) FROM CustomerWHERE LastName LIKE SMI%1917 / 52189 = .04SELECT COUNT(1) FROM OrdersWHERE OrderDate >= SYSDATE - 3055067 / 690671 = .08SELECT COUNT(1) FROM OrdersWHERE OrderStatus <> C3760 / 690671 = .005o .08.04i cpsda.005SQL Diagram
  • 2/21/2013 Confidential - Internal Use Only 27• Only 0.5% of rows are <> ‘C’• How about changing the query?– AND o.OrderStatus = I• Add an Index on OrderStatus– Collect histogramsSELECT OrderStatus, COUNT(1)FROM OrdersGROUP BY OrderStatusI 3760C 686911Data Skew Problems
  • 2/21/2013 Confidential - Internal Use Only 28New Execution PlanCREATE INDEX order_status ON Orders (OrderStatus)Execution Stats – 7,221 Logical Reads-----------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1581 | 301K| 3722 (1)| 00:00:45 ||* 1 | HASH JOIN | | 1581 | 301K| 3722 (1)| 00:00:45 ||* 2 | HASH JOIN | | 1581 | 270K| 2655 (1)| 00:00:32 || 3 | NESTED LOOPS | | | | | || 4 | NESTED LOOPS | | 1581 | 101K| 2587 (1)| 00:00:32 ||* 5 | HASH JOIN | | 303 | 15756 | 170 (1)| 00:00:03 ||* 6 | TABLE ACCESS BY INDEX ROWID| ORDERS | 303 | 5757 | 33 (0)| 00:00:01 ||* 7 | INDEX RANGE SCAN | ORDER_STATUS | 3811 | | 9 (0)| 00:00:01 ||* 8 | VIEW | index$_join$_001 | 2055 | 67815 | 137 (1)| 00:00:02 ||* 9 | HASH JOIN | | | | | ||* 10 | INDEX RANGE SCAN | CUSTOMER_LN | 2055 | 67815 | 14 (8)| 00:00:01 || 11 | INDEX FAST FULL SCAN | PK_CUSTOMER | 2055 | 67815 | 123 (0)| 00:00:02 ||* 12 | INDEX RANGE SCAN | PK_ORDERINFO | 5 | | 2 (0)| 00:00:01 || 13 | TABLE ACCESS BY INDEX ROWID | ITEM | 5 | 70 | 8 (0)| 00:00:01 || 14 | TABLE ACCESS FULL | PRODUCT | 8914 | 948K| 68 (0)| 00:00:01 || 15 | TABLE ACCESS FULL | SHIPMENTDETAILS | 836K| 15M| 1064 (1)| 00:00:13 |-----------------------------------------------------------------------------------------------------
  • 2/21/2013 Confidential - Internal Use Only 29• Tuning SQL gives more “bang for the buck”• Make sure you are tuning the correct query• Use Wait Events and Response Time Analysis– Locking problems may not be a Query Tuning issue– Wait events tell you where to start• Use “Real Execution Plans”– Get plan_hash_value from V$SESSION, V$SQL– Pass it to V$SQL_PLAN to get Real Plan• Ignite – Does All of Above For You– OEM Does not Give you Enough Details• SQL Diagramming - “Get it right the First Time”Takeaway Points
  • Q&AThank you for attending.More questions?Contact Dean atDeanRichards@confio.comDownload free trial of Ignite athttp//www.confio.com2/21/2013 30