Proven Process For SQL Tuning: Dean Richards Senior DBA, Confio Software
Proven Process For SQL Tuning: Dean Richards Senior DBA, Confio Software
SQL Tuning
Dean Richards
Senior DBA, Confio Software
1
Who Am I?
3
Agenda
Introduction
Challenges
Identify - Which SQL and Why
Gather – Details about SQL
Tune – Case Study
Monitor – Make sure it stays tuned
4
Introduction
5
Challenges
Have a Method
• Tracing a Session / Process
• User / Batch Job Complaints
• Highest I/O (LIO, PIO)
• SQL Performing Full Table Scans
• Known Poorly Performing SQL
• Response / Wait Times (Ignite, AWR, etc)
7
Identify – End-to-End
Business Aspects
• Who registered yesterday for SQL Tuning
• Who uses this information?
• Why does the business need to know this?
• How often is the information needed?
Technical Information
• Review Tables, Indexes, Triggers, Views, etc
• Understand Relationships
• Know the Data (High Level)
End-to-End Process
• Understand Application Architecture
• What Portion of the Total Time is Database
8
Identify – End-to-End Time
9
Wait Event Information
V$SESSION
V$SESSION_WAIT
SID
USERNAME SID
SQL_ID EVENT
PROGRAM P1, P1RAW, P2, P2RAW, P3, P3RAW
MODULE STATE (WAITING, WAITED…)
ACTION
PLAN_HASH_VALUE • Oracle 10g added this info to V$SESSION
ROW_WAIT_OBJ#
PARSE_CALLS OBJECT_TYPE
BUFFER_GETS
10
DISK_READS
Wait Event Information
11
Wait Time Scenario
12
Identify – Simplification
13
Identify – Summary
14
Gather - Metrics
15
Gather – Execution Plan
EXPLAIN PLAN
• Estimated execution plan - can be wrong for many
reasons
V$SQL_PLAN (Oracle 9i+)
• Real execution plan
• Use DBMS_XPLAN for display
Tracing (all versions)
• Works when you know a problem will occur
ALTER SESSION SET tracefile_identifier = dean;
ALTER SESSION SET sql_trace = true;
Historical – AWR, Confio Ignite
16
All Plans Not Equal
SELECT company, attribute
FROM data_out WHERE segment = :B1
Wait Time – 100% on “db file scattered read”
Plan from EXPLAIN PLAN
17
Gather – Bind Values
V$SQL_BIND_CAPTURE
• STATISTICS_LEVEL = TYPICAL or ALL
• Collected at 15 minute intervals
SELECT name, position, datatype_string, value_string
FROM v$sql_bind_capture
WHERE sql_id = '15uughacxfh13';
18
Gather – Table / Index Stats
Use TuningStats.sql
• http://support.confio.com/kb/1534
Provides data on objects in execution plans.
• Table sizes
• Existing indexes
• Cardinality of columns
• Segment sizes
• Histograms and Data Skew
• Many things the CBO uses
Run it for any table involved in query
19
Example SQL Statement
21
Execution Plan
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 95 |
| 1 | NESTED LOOPS | | 1 | 167 | 95 |
| 2 | NESTED LOOPS | | 1 | 138 | 94 |
| 3 | NESTED LOOPS | | 7 | 357 | 87 |
| 4 | VIEW | VW_SQ_1 | 201 | 7035 | 87 |
|* 5 | FILTER | | | | |
| 6 | HASH GROUP BY | | 201 | 3417 | 87 |
|* 7 | FILTER | | | | |
|* 8 | TABLE ACCESS FULL | REGISTRATION | 80000 | 1328K| 76 |
|* 9 | INDEX UNIQUE SCAN | SYS_C0036920 | 1 | 16 | 0 |
|* 10 | TABLE ACCESS BY INDEX ROWID| CLASS | 1 | 87 | 1 |
|* 11 | INDEX UNIQUE SCAN | SYS_C0036919 | 1 | | 0 |
| 12 | TABLE ACCESS BY INDEX ROWID | STUDENT | 1 | 29 | 1 |
|* 13 | INDEX UNIQUE SCAN | SYS_C0036918 | 1 | | 0 |
------------------------------------------------------------------------------
5 - filter((MAX("SIGNUP_DATE")>=TRUNC(SYSDATE@!-1) AND
MAX("SIGNUP_DATE")<=TRUNC(SYSDATE@!)))
7 - filter(TRUNC(SYSDATE@!-1)<=TRUNC(SYSDATE@!))
8 - filter("CANCELLED"='N')
9 - access("R1"."STUDENT_ID"="STUDENT_ID" AND "R1"."CLASS_ID"="CLASS_ID" AND
"SIGNUP_DATE"="VW_COL_1")
filter(("SIGNUP_DATE">=TRUNC(SYSDATE@!-1) AND "SIGNUP_DATE"<=TRUNC(SYSDATE@!)))
10 - filter(UPPER("C"."NAME“)='SQL TUNING')
11 - access("CLASS_ID"="C"."CLASS_ID")
13 - access("S"."STUDENT_ID"="STUDENT_ID")
22
Gather – Summary
Execution Plan
• V$SQL_PLAN
• Do not use EXPLAIN PLAN
• DBMS_XPLAN
Bind Values
• V$SQL_BIND_CAPTURE
• Tracing
Table and Index Statistics
ERD
23
Tune – Create SQL Diagram
registration .04
5 30
1 1
2 / 1000 = .002
24
New Plan
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 10|
|* 1 | FILTER | | | | |
| 2 | NESTED LOOPS | | 1 | 132 | 7|
| 3 | NESTED LOOPS | | 1 | 103 | 6|
|* 4 | TABLE ACCESS BY INDEX ROWID | CLASS | 1 | 87 | 5|
|* 5 | INDEX RANGE SCAN | CL_UNAME | 4 | | 1|
|* 6 | INDEX RANGE SCAN | REG_ALT | 1 | 16 | 1|
| 7 | SORT AGGREGATE | | 1 | 17 | |
|* 8 | TABLE ACCESS BY INDEX ROWID| REGISTRATION | 1 | 17 | 3|
|* 9 | INDEX RANGE SCAN | REG_ALT | 1 | | 2|
| 10 | TABLE ACCESS BY INDEX ROWID | STUDENT | 1 | 29 | 1|
|* 11 | INDEX UNIQUE SCAN | SYS_C0036918 | 1 | | 0|
--------------------------------------------------------------------------------
25
Query 2
26
Tune – Create SQL Diagram
1 1
student class
C COUNT(1)
- ----------
Y 638
N 79345
dbms_stats.gather_table_stats(
ownname => 'STDMGMT',
tabname => 'REGISTRATION',
method_opt=>'FOR COLUMNS cancelled SIZE AUTO')
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 7|
|* 1 | FILTER | | | | |
|* 2 | TABLE ACCESS BY INDEX ROWID| REGISTRATION | 1 | 17 | 7|
|* 3 | INDEX RANGE SCAN | REG_CAN | 754 | | 2|
----------------------------------------------------------------------------
29
Monitor
30
Confio Software - Monitor
33