Oracle Perf Presentation
Oracle Perf Presentation
Sqlplusscott/tiger@prod
SQL>select * from emp;
SQL>update emp set sallary=30000 where empid=10;
SQL>commit;
1. Once we hit sqlplus statement as above client process(user)
access sqlnet listener.
2. Sql net listener confirms that DB is open for buisness & create
server process.
3. Server process allocates PGA. Connected Message returned to
user.
4. SQL>select * from emp;
5. Server process checks the SGA to see if data is already in buffer
cache.
6. If not then data is retrived from disk and copied into SGA (DB
Cache).
7. Data is returned to user via PGA & server process.
8. Now another statement is SQL>Update emp set sallary=30000
where empid=10;
9. Server process (Via PGA) checks SGA to see if data is already
there in buffer cache.
10. In our situation chances are the data is still in the SGA (DB
Execution Plan
---------------------------------------------------------0
SELECT STATEMENT Optimizer=CHOOSE
1 0 NESTED LOOPS
2 1
TABLE ACCESS (FULL) OF 'EMP'
3 1
TABLE ACCESS (BY INDEX ROWID) OF 'DEPT'
4 3
INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)
Statistics
---------------------------------------------------------81 recursive calls
4 db block gets
27 consistent gets
0 physical reads
0 redo size
941 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
DISPLAY_CURSOR Function
CONN / AS SYSDBA
GRANT SELECT ON v_$session TO scott;
GRANT SELECT ON v_$sql TO scott;
GRANT SELECT ON v_$sql_plan TO scott;
GRANT SELECT ON v_$sql_plan_statistics_all TO scott;
CONN scott/tiger
SELECT *
FROM emp e, dept d
WHERE e.deptno = d.deptno
AND e.ename = 'SMITH';
SET LINESIZE 130
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(format => 'ADVANCED'));
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------SQL_ID gu62pbk51ubc3, child number 0
------------------------------------SELECT * FROM emp e, dept d WHERE e.deptno = d.deptno AND
= 'SMITH'
e.ename
TKPROF
File Location
SELECT value
FROM v$diag_info
WHERE name = 'Default Trace File';
Trace Levels
SQL> ALTER SESSION SET EVENTS '10046 trace name context forever, level 12';
Join Types
Sort Merge Join (SMJ)
Nested Loops (NL)
Hash Join
Sort Merge Join
MERGE
/
\
SORT
SORT
|
|
Row Source 1 Row Source 2
Nested Loops
First we return all the rows from row source 1 Then we probe row source 2 once for each
row returned from row source 1
Row source 1
~~~~~~~~~~~~
Row 1 --------------- Probe ->
Row source 2
Row 2 --------------- Probe ->
Row source 2
Row 3 --------------- Probe ->
Row source 2
Row source 1 is known as the outer table
Row source 2 is known as the inner table
Hash Join
SQL> explain plan for
select /*+ use_hash(emp) */ empno
from emp,dept
where emp.deptno = dept.deptno;
Query Plan
---------------------------SELECT STATEMENT [CHOOSE] Cost=3
HASH JOIN
TABLE ACCESS FULL DEPT
TABLE ACCESS FULL EMP
Cartesian Product
SQL> explain plan for
select emp.deptno,dept,deptno
from emp,dept
Query Plan
-----------------------------SLECT STATEMENT [CHOOSE] Cost=5
MERGE JOIN CARTESIAN
TABLE ACCESS FULL DEPT
SORT JOIN
TABLE ACCESS FULL EMP
Operations
Operations that show up in explain plans
sort
filter
view
Sorts
In the following example the select contains an inline view which cannot be merged:
SQL> explain plan for
select ename,tot
from emp,
(select empno,sum(empno) tot from big_emp group by empno) tmp
where emp.empno = tmp.empno;
Query Plan
-----------------------SELECT STATEMENT [CHOOSE]
HASH JOIN
TABLE ACCESS FULL EMP [ANALYZED]
VIEW
SORT GROUP BY
INDEX FULL SCAN BE_IX
Parallel Query
select /*+ parallel(B,4) parallel(A,4) */
A.dname, avg(B.sal), max(B.sal)
from dept A, emp B
where A.deptno = B.deptno
group by A.dname
order by max(B.sal), avg(B.sal) desc;
OBJECT_NAME
OBJECT_NODE OTHER
------------------------------- ----------- ------SELECT STATEMENT
Cost = ??
SORT ORDER BY
:Q55004
**[7]**
SORT GROUP BY
:Q55003
**[6]**
MERGE JOIN
:Q55002
**[5]**
SORT JOIN
:Q55002
**[4]**
TABLE ACCESS FULL emp :Q55001
**[2]**
SORT JOIN
:Q55002
**[3]**
TABLE ACCESS FULL dept :Q55000
**[1]**
Execution Plan #2 -- OTHER column
**[1]** (:Q55000) "PARALLEL_FROM_SERIAL"
Serial execution of SELECT DEPTNO, DNAME FROM DEPT
**[2]** (:Q55001) "PARALLEL_TO_PARALLEL"
SELECT /*+ ROWID(A1)*/
A1."DEPTNO" C0, A1."SAL" C1
FROM "EMP" A1
WHERE ROWID BETWEEN :1 AND :2
**[3]** (:Q55002) "PARALLEL_COMBINED_WITH_PARENT"
**[4]** (:Q55002) "PARALLEL_COMBINED_WITH_PARENT"
**[5]** (:Q55002) "PARALLEL_TO_PARALLEL"
SELECT /*+ ORDERED USE_MERGE(A2)*/
A2.C1 C0, A1.C1 C1
FROM :Q55001 A1,:Q55000 A2
WHERE A1.C0=A2.C0
**[6]** (:Q55003) "PARALLEL_TO_PARALLEL"
SELECT MAX(A1.C1) C0, AVG(A1.C1) C1, A1.C0 C2
FROM :Q55002 A1
GROUP BY A1.C0
**[7]** (:Q55004) "PARALLEL_FROM_SERIAL"
Quick Fixes
There are a number of very common SQL problems that are easy to identify and
easy to fix.
Are the underlying tables and indexes analyzed?
Does the SQL already have optimizer hints?
Do you have any Cartesian Products?
To find out whether your SQL is performing a Cartesian Product, run it through
Explain Plan and search for a step that looks like this:
MERGE JOIN (CARTESIAN)
There are several situations where Oracle will use a Cartesian Product
You have not specified any join conditions in the WHERE clause of your SQL. For
example:
SELECT a.column1, b.column3
FROM table_a a, table_b b
WHERE a.column9 = 'X'
AND b.column5 >= to_date('13-JAN-2003','DD-MON-YYYY')
For low volume SQLs, are there any Full Table/Partition Scans?
Full Table Scans
Full table scans have an image problem. Many Oracle developers - usually those
working on OLTP systems - are told early in their careers that Full Table Scans are
bad. Period! Many will then hold on to this prejudice and never learn the truth.
Execution Plan
---------------------------------------------------------0
SELECT STATEMENT Optimizer=CHOOSE
1 0 NESTED LOOPS
2 1
TABLE ACCESS (FULL) OF 'EMP'
3 1
TABLE ACCESS (BY INDEX ROWID) OF 'DEPT'
4 3
INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)
Statistics
---------------------------------------------------------81 recursive calls
4 db block gets
27 consistent gets
0 physical reads
0 redo size
941 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed