You are on page 1of 44

Performance Tuning SQL and PL/SQL

Presentation By P. S. Mukesh Yadav and Suresh C Mishra

11/10/2008

VESL TECHNOLOGIES LTD

Tips in SQL Tips in PL/SQL

Topics

11/10/2008

VESL TECHNOLOGIES LTD

Tips in SQL
Limit the use of sub queries; often they can be replaced with a JOIN. Use EXISTS and more specific conditions in the where clause instead of the DISTINCT clause to eliminate duplicates. Never Mix Datatypes.Use character and number appropriately according to the usage.

11/10/2008

VESL TECHNOLOGIES LTD

Example of First Tip


SELECT ename FROM emp WHERE deptno IN (SELECT deptno FROM emp WHERE comm = 10 AND sal>4000);
SELECT ename FROM emp d WHERE EXISTS ( SELECT e.deptno FROM emp e WHERE 1=1 and e.deptno = d.deptno AND e.comm = 10 AND e.sal > 4000);

SELECT ename FROM emp e,dept d WHERE e.deptno = d.deptno AND e.comm = 10 AND e.sal > 4000

11/10/2008

VESL TECHNOLOGIES LTD

Example of Second Tip


Ex :
select distinct ooha.order_type_id,ooha. order_number from oe_order_headers_all ooha,oe_transaction_type s_tl ottt where ooha.order_type_id = ottt.transaction_type_id
SELECT ooha.order_type_id,ooha.order_n umber FROM oe_order_headers_all ooha WHERE EXISTS (SELECT 1 FROM oe_transaction_types_tl ottt WHERE ooha.order_type_id = ottt.transaction_type_id);

11/10/2008

VESL TECHNOLOGIES LTD

Tips in SQL Contd..


Avoid the use of NOT IN.Instead, a NOT EXISTS sub query may run faster. Use Minus Operator instead of Exists sub queries(Not in and Not Exists) results in faster execution plan. Rewrite (negative(ex : not in)) sub queries as outer joins to improve performance. Never use numbers in sorting.
11/10/2008 VESL TECHNOLOGIES LTD 6

Contd.
Ex :
SELECT * FROM EMP A WHERE DEPTNO NOT IN (SELECT DEPTNO FROM DEPT WHERE DEPTNO=A.DEPTNO) SELECT * FROM EMP A WHERE NOT EXISTS (SELECT 1 FROM DEPT WHERE DEPTNO=A.DEPTNO)

select * from ap_invoices_all where invoice_id not in(select invoice_id from ap_invoice_payments_all )

SELECT aia.invoice_id FROM ap_invoices_all aia, ap_invoice_payments_all aipa WHERE aia.invoice_id = aipa.invoice_id(+);

11/10/2008

VESL TECHNOLOGIES LTD

Contd.
Ex :
select * from ap_invoices_all where invoice_id not in(select invoice_id from ap_invoice_payments_all )
SELECT * FROM ap_invoices_all aia WHERE NOT EXISTS (SELECT * FROM ap_invoice_payments_all WHERE invoice_id = aia.invoice_id)

select * from ap_invoices_all where invoice_id in (select invoice_id from ap_invoices_all minus select invoice_id from ap_invoice_payments_all )

11/10/2008

VESL TECHNOLOGIES LTD

Tips in SQL Contd..


Avoid running a query in a loop.Make use of UNION and execute it at the end of the loop. Avoid the LIKE predicate.Always replace LIKE with = when appropriate. Use LIKE rather than the SUBSTR function. Avoid Where Column Like '%string'. Consider Indexes for Max() and Min().

11/10/2008

VESL TECHNOLOGIES LTD

Contd.
Ex :
select * from dept where dname like 'RESEARCH'

select * from dept where dname = 'RESEARCH'

select ename from emp where ename like X%

select ename from emp where substr(ename,1,1) = X

11/10/2008

VESL TECHNOLOGIES LTD

10

Tips in SQL Contd..


Use Decode and Case for complex aggregations. Use WHERE instead of HAVING. Use UNION ALL instead of UNION. Prefer using GROUP BY only when any aggregate functions are present. Avoid usage of TO_CHAR and use TRUNC instead.
11/10/2008 VESL TECHNOLOGIES LTD 11

Contd.
Ex : Ex :
SELECT E_Name FROM Employees_Norway UNION ALL SELECT E_Name FROM Employees_USA

SELECT E_Name FROM Employees_Norway UNION SELECT E_Name FROM Employees_USA

select * from emp where to_char(emp_joindate, mmddyyyy) < to_char(sysdat e,mmddyyyy)

select * from emp where emp_joindate < trunc (sysdate)

11/10/2008

VESL TECHNOLOGIES LTD

12

SELECT COUNT(*) FROM emp WHERE status = 'Y' AND emp_name LIKE 'SMITH%';

SELECT COUNT(*) FROM emp WHERE status = 'N' AND emp_name LIKE 'SMITH%';

Ex :
SELECT DEPTID, SUM(SALARY) FROM EMP GROUP BY DEPTID HAVING DEPTID = 100;

SELECT COUNT(DECODE(status, 'Y', 'X', NULL)) Y_count, COUNT(DECODE(status, 'N', 'X', NULL)) N_count FROM emp WHERE emp_name LIKE 'SMITH%';

SELECT DEPTID, SUM(SALARY) FROM EMP WHERE DEPTID = 100 GROUP BY DEPTID;

11/10/2008

VESL TECHNOLOGIES LTD

13

Contd.
SELECT COUNT (*) FROM emp WHERE sal < 2000; SELECT COUNT (*) FROM emp WHERE sal BETWEEN 2000 AND 4000; SELECT COUNT (*) FROM emp WHERE sal>4000;

SELECT COUNT (CASE WHEN sal < 2000 THEN 1 ELSE null END) count1, COUNT (CASE WHEN sal BETWEEN 2001 AND 4000 THEN 1 ELSE null END) count2, COUNT (CASE WHEN sal > 4000 THEN 1 ELSE null END) count3 FROM emp;

11/10/2008

VESL TECHNOLOGIES LTD

14

Tips in SQL Contd..


Use NVL to check against a number instead of the NULL value. Use <= 99 and >= 1 instead of < 100 and > 0 for faster comparisons. Avoid using functions on indexed columns. Use SET TIMING ON to test the execution time of a slow query. Use EXPLAIN PLAN to view the execution steps of a slow query.
11/10/2008 VESL TECHNOLOGIES LTD 15

Contd.
Ex :
select cdl.* from cs_incidents_all_b ciab, jtf_tasks_b jtb, jtf_task_assignments jta, csf_debrief_headers cdh, csf_debrief_lines cdl where ciab.incident_id = jtb.source_object_id and jtb.task_id = jta.task_id and jta.task_assignment_id = cdh.task_assignment_id and cdh.debrief_header_id = cdl.debrief_header_id and ciab.incident_number = '1097852'

11/10/2008

VESL TECHNOLOGIES LTD

16

Contd.
Operation SELECT STATEMENT Optimizer Mode=CHOOSE TABLE ACCESS BY INDEX ROWID NESTED LOOPS NESTED LOOPS NESTED LOOPS NESTED LOOPS TABLE ACCESS BY INDEX ROWID INDEX UNIQUE SCAN TABLE ACCESS FULL TABLE ACCESS BY INDEX ROWID INDEX RANGE SCAN TABLE ACCESS BY INDEX ROWID INDEX RANGE SCAN INDEX RANGE SCAN Object Name Rows Bytes 4 3 4 1 1 1 1 1 1 1 2 1 1 4 Cost Object Node In/Out 1134 414 3 776 1134 56 1131 42 1129 22 1126 12 4 2 10 1122 20 3 2 14 2 1 2 PStart PStop

CSF_DEBRIEF_LINES

CS_INCIDENTS_ALL_B CS_INCIDENTS_U2 JTF_TASKS_B JTF_TASK_ASSIGNMENTS JTF_TASK_ASSIGNMENTS_N2 CSF_DEBRIEF_HEADERS CSF_DEBRIEF_HEADERS_N1 CSF_DEBRIEF_LINES_N1

11/10/2008

VESL TECHNOLOGIES LTD

17

Contd.
Ex :
select sys.resourceID, sys.client_version0 from dbo.v_R_System as sys where UPPER(netbios_name0) = 'COMPUTER'

select sys.resourceID, sys.client_version0 from dbo.v_R_System as sys where netbios_name0 = 'COMPUTER

11/10/2008

VESL TECHNOLOGIES LTD

18

Tips in SQL Contd..


Remove unnecessary large full table scans. Minimize outer joins and use them only if necessary. Only use CHAR for data that must be an exact length such as phone numbers or gender identification fields because it pads variable length data with white-space that will cause string comparisons to fail.

11/10/2008

VESL TECHNOLOGIES LTD

19

Tips in SQL Contd..


Use an indexed column or primary key column when counting rows. Avoid unnecessary sorting. Always better to use base tables instead of views. If a view is in a query,try to optimize the view first before optimizing the query. Always place all the hard-coded values at the end of a query.
11/10/2008 VESL TECHNOLOGIES LTD 20

Contd.
Ex :
select count(*) From emp select count(emp _id) from emp;

11/10/2008

VESL TECHNOLOGIES LTD

21

Tips in SQL Contd..


Using the indexes carefully. Position of Tables in the proper order. Sequence of Joins in the Where Clause. Put the queries as simple as possible. Avoid using of NOT when ever dealing with Indexed Columns. Avoid usage of ! Operator use > instead. Always use a column list in your INSERT statements.
11/10/2008 VESL TECHNOLOGIES LTD 22

Contd.
Ex :
select * from emp where emp_id != 007 select * from emp where emp_id > 0

INSERT INTO EuropeanCountries VALUES (1, 'Ireland')

INSERT INTO EuropeanCountries (CountryID, CountryName) VALUES (1, 'England')

11/10/2008

VESL TECHNOLOGIES LTD

23

Make Use of rownum. To Check Duplicate Data in a Query.

Tips in SQL Contd..

Use SQL standards and conventions to reduce parsing.


Make sure to do INSERT,UPDATE and DELETE operations prior checking the data with a SELECT statement with proper conditions in the where clause. Recheck whether any joins are missing.
11/10/2008 VESL TECHNOLOGIES LTD 24

Contd.
Ex :
SELECT DOCUMENT_NO,COUNT(*) FROM documents GROUP BY DOCUMENT_NO HAVING COUNT(*) > 1;

11/10/2008

VESL TECHNOLOGIES LTD

25

Tips in SQL Contd..


Use Column Names instead of * in a SELECT Statement. Use an index on the most queried columns in SELECT, WHERE, and JOIN statements. Use BETWEEN instead of IN. Make sure all joined tables have a matching join condition. Make sure columns selected from multiple tables are dereferenced by an alias.
VESL TECHNOLOGIES LTD

11/10/2008

26

Contd.
Ex :
SELECT empno FROM emp WHERE empno IN (508858, 508859, 508860, 508861,508862, 508863, 508864)

SELECT empno FROM emp WHERE empno BETWEEN 508858 and 508864

11/10/2008

VESL TECHNOLOGIES LTD

27

Tips in SQL Contd..


Call Functions in SQL Queries. Minimize Table Lookups in a Query. Use where instead of Order By. Never do a calculation on an indexed column. Give the names from _tl tables instead of hardcoding the id.Ex : Status Add Who Columns for any new table created for easier archiving.

11/10/2008

VESL TECHNOLOGIES LTD

28

Contd.
Ex :
select tab_name from tables where tab_name = (select tab_name from tab_columns where version = 604) and db_ver = (select db_ver from tab_columns where version = 604) select tab_name from tables where (tab_name, db_ver) = (select tab_name,db_ver from tab_columns where version = 604)

update emp set emp_cat = (select max(category) from emp_categories),sal = (select max(salrange) from emp_categories)where emp_dept = 20

update emp set (emp_cat , sal )= (select max(category), max(salrange) from emp_categories) Where emp_dept = 20

11/10/2008

VESL TECHNOLOGIES LTD

29

Contd.
Ex :
select * from emp where sal*12>25000

select * from emp where sal>25000/12

11/10/2008

VESL TECHNOLOGIES LTD

30

Tips in SQL Contd..


Use sub queries and joins instead of multiple separate queries. Use >= instead of > Use Union in place of OR for Indexed Columns. Use the EXISTS clause or = operator instead of the IN clause whenever you need a single record.

11/10/2008

VESL TECHNOLOGIES LTD

31

Contd.
Ex :
select * from oe_order_headers_all where order_number>3 select * from oe_order_headers_all where order_number>=4

11/10/2008

VESL TECHNOLOGIES LTD

32

Tips in SQL Contd..


Avoid IS NULL & IS NOT NULL on Indexed Columns.Use >=0 if necessary. Use a system generated ID as the primary key to avoid duplicates. Use Optimizer Hints. Generate a tkprof and observe the trace file. Focus on critical transactions(Production Data)..

11/10/2008

VESL TECHNOLOGIES LTD

33

Contd.
Ex :
/*+index(t1) index(t2)..index(tn)*/ /*+FULL(t1) FULL(t2)FULL(tn)*/ /*+OPTIMIZER_GOAL=CHOOSE*/ /*+OPTIMIZER_GOAL=FIRST_ROWS*/ /*+ORDERED*/ /*+RULE*/ /*+OPTIMIZER_GOAL=ALL_ROWS*/ /*+OPTIMIZER_GOAL=ORDERED*/ /*+OPTIMIZER_GOAL=RULE*/ /*+USE_NL(t1,t2,t3,t4,t5,t6) ORDERED */

11/10/2008

VESL TECHNOLOGIES LTD

34

Tips in PL/SQL
Break the piece of code into small blocks to achieve modularity. Grouping related logic as a single block. Use Packages for each major functionality. Avoid hard-coding.

11/10/2008

VESL TECHNOLOGIES LTD

35

Tips in PL/SQL Contd..

Follow PL/SQL Coding standards for procedures, variables, table types,rec types, functions and packages. Encapsulate your SQL. Avoid repeating the SQL in different places. Exception Handling. Usage of Bind Variables and Global Variables. Make Function Calls efficiently.

11/10/2008

VESL TECHNOLOGIES LTD

36

Tips in PL/SQL Contd..


Use BULK COLLECT when there is huge amount of data to be fetched from a select query in a cursor. Use FOR ALL. Use Bulk Bind. Reorder Conditional Tests to put the Least Expensive First. Logic in a simplest way. Usage of End Labels. Avoid usage of mutating tables.
11/10/2008 VESL TECHNOLOGIES LTD 37

Ex :

CREATE OR REPLACE FUNCTION get_a_mess_o_emps (deptno_in IN dept.depno%TYPE) RETURN emplist_t IS emplist emplist_t := emplist_t(); TYPE numTab IS TABLE OF NUMBER; TYPE charTab IS TABLE OF VARCHAR2(12); TYPE dateTab IS TABLE OF DATE; enos numTab; names charTab; hdates dateTab; BEGIN SELECT empno, ename, hiredate BULK COLLECT INTO enos, names, hdates FROM emp WHERE deptno = deptno_in; emplist.EXTEND(enos.COUNT); FOR i IN enos.FIRST..enos.LAST LOOP emplist(i) := emp_t(enos(i), names(i), hiredates(i)); END LOOP; RETURN emplist; END;
VESL TECHNOLOGIES LTD 38

Contd.

11/10/2008

Contd.
Ex :
PROCEDURE reality_meets_dotcoms (deptlist dlist_t) IS BEGIN FORALL aDept IN deptlist.FIRST..deptlist.LAST DELETE emp WHERE deptno = deptlist(aDept); END;

11/10/2008

VESL TECHNOLOGIES LTD

39

Tips in PL/SQL Contd..


Use Anchored declaration during declaration of variables. Reduce N/w traffic. Make use of user_ tables or views in the custom packages. Use Standard Public Apis. Group related sub-programs in a Package. Make use of Optimizer Hints.

11/10/2008

VESL TECHNOLOGIES LTD

40

Tips in PL/SQL Contd..


Make use of the apis being called in the standard forms of Oracle Applications. Minimize Datatype Conversions. Use of CASE statements, is a much better alternative to nested if-elsif statements. Declare Local Variables Oracle Datatype. Make Loops as Efficient as Possible.

11/10/2008

VESL TECHNOLOGIES LTD

41

Tips in PL/SQL Contd..


Use of pls_integer to declare integers and binary_float or binary_double for floating point. Replace and simplify IF statements with Boolean expressions. Never exit from a FOR or WHILE loops. Never declare the FOR loop index (either an integer or a record). Minimize the function Calls.
11/10/2008 VESL TECHNOLOGIES LTD 42

Contd
Unit Testing. Debugging. Analysis on the Exceptions. Test Cases.

11/10/2008

VESL TECHNOLOGIES LTD

43

Contd

Thank You

11/10/2008

VESL TECHNOLOGIES LTD

44