Académique Documents
Professionnel Documents
Culture Documents
SQL Writing Process SQL Standards Using Indexes The Optimizer FROM, WHERE Clauses EXPLAIN SQL Trace Sub-Selects and Joins Tips and Tricks
1
Caveat
Although many of these principles apply to all databases, Oracle will be used in the examples.
I'M FINISHED!
Pre-Tuning Questions
How long is too long? Is the statement running on near-production volumes? Is the optimal retrieval path being used? How often will it execute? When will it execute?
SQL Standards
Why are SQL standards important? Maintainability, readability Performance: If SQL is the same as a (recently) executed statement, it can be re-used instead of needing to be reparsed
SQL Standards
Question: which of these statements are the same? A. SELECT LNAME FROM EMP WHERE EMPNO = 12; B. SELECT lname FROM emp WHERE empno = 12; C. SELECT lname FROM emp WHERE empno = :id; D. SELECT lname FROM
WHERE empno = 12; emp
SQL Standards
Answer: None Whitespace, case, bind variables vs. constants all matter Using standards helps to ensure that equivalent SQL can be reused.
10
13
Table: EMP
5 5, 9 empno 4 9 1 3 5 2 7 8 6 fname lisa jackie john larry jim mary harold mark gene lname ... baker miller larson jones clark smith simmons burns harris
7 8 9
14
Indexes: Caveats
Sometimes a table scan cannot be avoided Not every column should be indexed--there is performance overhead on Inserts, Updates, Deletes Small tables may be faster with a table scan Queries returning a large number (> 5-20%) of the rows in the table may be faster with a table scan
15
Must use the leading column(s) of the index for the index to be used
16
Indexes: Functions
Using a function, calculation, or other operation on an indexed column disables the use of the Index
SELECT FROM WHERE ... WHERE * Will NOT use index emp TRUNC(hiredate) = TRUNC(SYSDATE); fname || lname = 'MARYSMITH';
SELECT * FROM emp WHERE hiredate BETWEEN TRUNC(SYSDATE) AND TRUNC(SYSDATE)+1 ... WHERE fname = 'MARY' WILL use index AND lname = 'SMITH';
17
Indexes: NOT
Using NOT excludes indexed columns:
SELECT FROM WHERE ... ... * dept deptno != 0; deptno NOT = 0; deptno IS NOT NULL;
18
The Optimizer
The WHERE/FROM rules on the following pages apply to the Rule-based optimizer (Oracle). If the Cost-based Optimizer is used, Oracle will attempt to reorder the statements as efficiently as possible (assuming statistics are available). DB2 and Sybase use only a Cost-based optimizer The Optimizer's access paths can be overridden in Oracle and Sybase (not DB2)
19
20
21
EMP shares columns with DEPT and SALGRADE, so use as the driving table
22
23
SELECT * CPU = 10 sec FROM emp E WHERE 25 > (SELECT COUNT(*) FROM emp M WHERE M.mgr = E.empno) AND E.sal > 50000
24
26
SELECT E.* FROM emp E, dept D WHERE D.dname = 'SALES' AND D.deptno = E.deptno;
29
JOIN: better than Exists if the number of matching rows in DEPT is large
Explain
Display the access path the database will use (e.g., use of indexes, sorts, joins, table scans) Oracle: Sybase: DB2: EXPLAIN SHOWPLAN EXPLAIN
Oracle Syntax:
EXPLAIN PLAN SET STATEMENT_ID = 'statement id' INTO PLAN_TABLE FOR statement
Explain
Example 1: IN subquery
SELECT * FROM emp E WHERE E.deptno IN ( SELECT D.deptno FROM dept D WHERE D.dname = 'SALES');
Result:
3 joins MERGE JOIN 1 dynamic view SORT (JOIN) 2 table scans TABLE ACCESS (FULL) OF EMP 3 sorts SORT (JOIN) VIEW SORT (UNIQUE) TABLE ACCESS (FULL) OF DEPT
31
Explain
Example 2: "EXISTS" subquery
SELECT * FROM emp e WHERE EXISTS SELECT FROM WHERE AND ( 'x' dept d d.deptno = e.deptno d.dname = 'SALES'); 1 table scan 1 index scan 1 index access
Result:
FILTER TABLE ACCESS (FULL) OF EMP TABLE ACCESS (BY INDEX ROWID) OF DEPT INDEX (UNIQUE SCAN) OF PK_DEPT (UNIQUE)
32
Explain
Example 3: Join (no subquery)
SELECT E.* FROM emp E, dept D WHERE D.dname = 'SALES' AND D.deptno = E.deptno;
Result:
NESTED LOOPS TABLE ACCESS (FULL) OF EMP TABLE ACCESS (BY INDEX ROWID) OF DEPT INDEX (UNIQUE SCAN) OF PK_DEPT (UNIQUE)
33
SQL Trace
Use SQL Trace to determine the actual time and resource costs for for a statement to execute. Step 1: ALTER SESSION SET SQL_TRACE TRUE; Step 2: Execute SQL to be traced:
SELECT E.* FROM emp E, dept D WHERE D.dname = 'SALES' AND D.deptno = E.deptno;
SQL Trace
Step 4: Trace file is created in <USER_DUMP_DEST> directory on the server (specified by the DBA). Step 5: Run TKPROF (UNIX) to create a formatted output file:
tkprof echd_ora_15319.trc $HOME/prof.out table=plan_table explain=dbuser/passwd Trace file Formatted output file destination for Explain user/passwd for Explain
35
SQL Trace
Step 6: view the output file:
... SELECT E.* FROM emp E, dept D WHERE D.dname = 'SALES' AND D.deptno = E.deptno; call count ------- -----Parse 1 Execute 1 Fetch 2 ------- -----total 4
cpu elapsed disk query current -------- ---------- ---------- ---------- ---------0.00 0.00 0 0 0 0.00 0.00 0 0 0 0.00 0.00 4 19 3 -------- ---------- ---------- ---------- ---------0.00 0.00 4 19 3
Misses in library cache during parse: 0 Optimizer goal: CHOOSE Parsing user id: 62 (PMARKS) Rows ------6 14 14 14 Row Source Operation --------------------------------------------------NESTED LOOPS TABLE ACCESS FULL EMP TABLE ACCESS BY INDEX ROWID DEPT INDEX UNIQUE SCAN (object id 4628)
EXPLAIN output
36
37
SELECT e.deptno, e.lname EXISTS: no sort FROM emp e WHERE EXISTS ( SELECT 'X' FROM dept d WHERE d.deptno = e.deptno);
39
BEFORE: 3 statements INSERT INTO archive VALUES (:vardate, :varid, ...) are used to perform 1 Insert INSERT INTO emp_archive VALUES (SYSDATE, emp_seq.NEXTVAL, ...) AFTER: only 1 statement is needed
40
~ 50% faster
42
AFTER: only 1
44
Using a Sequence INSERT INTO emp VALUES (emp_seq.NEXTVAL, ...); ensures that you always have a unique number, or and does not require any SELECT emp_seq.NEXVAL table reads INTO :new_empno FROM dual;
46
PRESIDENT MANAGER ANALYST ANALYST MANAGER SALESMAN SALESMAN SALESMAN SALESMAN MANAGER
47
1,000 rows
49
50