Title: Tuning Oracle SQL
1Tuning Oracle SQL
- The Basics of Efficient SQL
- Common Sense Indexing
- The Optimizer
- Making SQL Efficient
- Finding Problem Queries
- Oracle Enterprise Manager
- Wait Event Interface
2The Basics of Efficient SQL
SELECT FROM division SELECT division_id, name,
city, state, country FROM division SELECT
division_id FROM division
- SELECT
- FOR UPDATE
- Filtering
- WHERE
- ORDER BY
- often ignored by the Optimizer
- depends on query and index complexity
- may need ORDER BY using composite indexes
- GROUP BY
3The Basics of Efficient SQL
- SELECT
- FOR UPDATE
- Filtering
- WHERE
- ORDER BY
- often ignored by the Optimizer
- depends on query and index complexity
- may need ORDER BY using composite indexes
- GROUP BY
Avoid unintentional full table scans SELECT
FROM division WHERE country LIKE 'a' Match
indexes Exact hits (equality) SELECT FROM
division WHERE division_id 1 Range scans /
skip scans / full index scans EXISTS (correlate)
faster than IN Biggest filters first Full table
scans can sometimes be faster
4The Basics of Efficient SQL
Resorts on result after WHERE and GROUP BY Dont
repeat sorting (ORDER BY often ignored) by
SELECT SELECT division_id FROM division ORDER BY
division_id by WHERE SELECT FROM division
WHERE division_id lt 10 ORDER BY
division_id GROUP BY SELECT state, COUNT(state)
FROM division GROUP BY state ORDER BY state by
DISTINCT SELECT DISTINCT(state) FROM division
ORDER BY state by indexes SELECT division_id
FROM division ORDER BY division_id
- SELECT
- FOR UPDATE
- Filtering
- WHERE
- ORDER BY
- often ignored by the Optimizer
- depends on query and index complexity
- may need ORDER BY using composite indexes
- GROUP BY
5The Basics of Efficient SQL
Resorts on result after WHERE and GROUP BY Dont
repeat sorting (ORDER BY often ignored) by
SELECT SELECT division_id FROM division ORDER BY
division_id by WHERE SELECT FROM division
WHERE division_id lt 10 ORDER BY
division_id GROUP BY SELECT state, COUNT(state)
FROM division GROUP BY state ORDER BY state by
DISTINCT SELECT DISTINCT(state) FROM division
ORDER BY state by indexes SELECT division_id
FROM division ORDER BY division_id
- SELECT
- FOR UPDATE
- Filtering
- WHERE
- ORDER BY
- often ignored by the Optimizer
- depends on query and index complexity
- may need ORDER BY using composite indexes
- GROUP BY
6The Basics of Efficient SQL
- SELECT
- FOR UPDATE
- Filtering
- WHERE
- ORDER BY
- often ignored by the Optimizer
- depends on query and index complexity
- may need ORDER BY using composite indexes
- GROUP BY
- Use WHERE not HAVING
GROUP BY SELECT state, COUNT(state) FROM division
GROUP BY state ORDER BY state HAVING (filters
aggregate) SELECT state, COUNT(state) FROM
division GROUP BY state HAVING COUNT(state) gt
1 use WHERE SELECT state, COUNT(state) FROM
division WHERE state 'NY' GROUP BY state not
HAVING SELECT state, COUNT(state) FROM division
GROUP BY state HAVING state 'NY'
7The Basics of Efficient SQL
- SELECT
- FOR UPDATE
- Filtering
- WHERE
- ORDER BY
- often ignored by the Optimizer
- depends on query and index complexity
- may need ORDER BY using composite indexes
- GROUP BY
- Use WHERE not HAVING
GROUP BY SELECT state, COUNT(state) FROM division
GROUP BY state ORDER BY state HAVING (filters
aggregate) SELECT state, COUNT(state) FROM
division GROUP BY state HAVING COUNT(state) gt
1 use WHERE SELECT state, COUNT(state) FROM
division WHERE state 'NY' GROUP BY state not
HAVING SELECT state, COUNT(state) FROM division
GROUP BY state HAVING state 'NY'
8The Basics of Efficient SQL
- Functions
- conversions
- miss indexes
- counteract with function based indexing
- avoid using
- DECODE
- CASE expressions
- set operators (UNION)
- Use sequences
- Use equality () or range scans (gt)
- avoid negatives (!, NOT)
- avoid LIKE
9The Basics of Efficient SQL
- Joins
- avoid Cartesian Products
- avoid anti joins
- avoid outer joins
- perhaps replace
- multiple table complex joins
- with subquery semi joins and inline views
- Be careful with views
10Common Sense Indexing
- Dont always need indexes
- table with few columns
- static data
- small tables
- appended tables (SQLLoader)
- How to index
- single column surrogate sequences
- dont override PK and FKs
- avoid nullable columns
11Common Sense Indexing
- Read write indexing
- BTree
- Often read only
- Bitmaps
- IOTs
- Clusters
12Common Sense Indexing
- Read write indexing
- BTree
- function based
- can help a lot
- get out of control
- everybody wants one
- reverse key
- surrogate keys
- High insertion rates
- not DW
- Oracle RAC
13Common Sense Indexing
- Often read only
- Bitmaps
- can be much faster than BTrees
- can deteriorate drastically over time
- twice as fast in my book
- at a previous client
- 1 year of DML activity
- 100s of times slower
- problem was nobody knew why
- and nobody wanted to change anything
14Common Sense Indexing
- Often read only
- IOTs
- small number of columns
- small tables
- heard good things in Oracle RAC
- even highly active DML environments
15The Optimizer
- Is intelligent
- better with simple queries
- Is usually correct
- Nothing is set in stone
- Verify SQL code efficiency
- use EXPLAIN PLAN
- SET AUTOTRACE ON EXPLAIN
- ORACLE_HOME/rdbms/admin/utlxplan.sql
16The Optimizer
- Everything cost based
- rule based is redundant
- Maintain statistics
- Dynamic sampling
- OPTIMIZER_DYNAMIC_SAMPLING
- Set TIMED_STATISTICS
- Histograms
- maintain as for statistics
- use for unevenly distributed indexes
17The Optimizer
- Tables
- full Table scans
- small static tables
- reading most of the rows
- over 10 for the Optimizer
- reading deleted rows
- parallel table scans
- sample table scans
- retrieve only portion of table by blocks or
- SELECT FROM generalledger SAMPLE(0.001)
- ROWID scans
18The Optimizer
- Indexes
- index unique scan
- index range scan
- reverse order index range scan
- index skip scan
- index full scan
- fast full index scan
- others (very specific)
19The Optimizer
- Joins
- nested loop join
- most efficient
- row sets both small
- one large and one small row set
- one sorted
- hash join
- both large with little difference
- temporary hash table generated
20The Optimizer
- More on joins
- sort merge join
- inefficient
- both rows sets sorted then merge sorted
- other join types
- semi joins
- bitmap joins
- star queries
- Cartesian joins
- outer joins (nested, hash or sort merge)
21The Optimizer
- Hints can change things
- influence the optimizer
- CURSOR_SHARING
- configuration parameter
- FORCE (OLTP)
- EXACT (DW)
- FIRST or ALL_ROWS
- DYNAMIC_SAMPLING
- change table scans
- FULL
22The Optimizer
- More on hints
- change index scans
- INDEX_ASC, INDEX_DESC
- INDEX_FFS
- INDEX_JOIN (join indexes)
- INDEX_SS_ASC or INDEX_SS_DESC
- NO_INDEX, NO_INDEX_FFS or NO_INDEX_SS
- change joins
- can change join type and influence with
parameters - parallel SQL
23Finding Problem Queries
- EXPLAIN PLAN
- SET AUTOTRACE ON EXPLAIN
- ORACLE_HOME/rdbms/admin/utlxplan.sql
- SQL Trace and TKPROF
24Finding Problem Queries
- Performance views
- VSQLAREA
- executions
- parsing
- sorting
- disk and buffer reads
- fetching
- VSQL
- optimizer cost
- CPU time
- elapsed time
Wait Event Interface
25Wait Event Interface
26Wait Event Interface
27Wait Event Interface
28Wait Event Interface
29Wait Event Interface
30Wait Event Interface
31Wait Event Interface
32Performance overview
33Database health overview
34Drilldown
35More drilldown
36TopSQL
37EXPLAIN PLAN
38Wait Event Interface
39Wait Event Interface
40Wait Event Interface
41Use the help files
Use the HELP FILES in Oracle Enterprise Manager