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