0% found this document useful (0 votes)
76 views

Oracle Performance Tuning 101 - Developer Perspective 090528 - 2

Uploaded by

k
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
76 views

Oracle Performance Tuning 101 - Developer Perspective 090528 - 2

Uploaded by

k
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 22

Oracle Performance

Tuning 101
Developer Perspective
Day 2

Karen Liu ([email protected])


May 20, 2009

071024 © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 1
Agenda
 Performance Tuning
Common Performance Problems (day 1)
Diagnostic Tools (day 1)
How to Identify SQL Performance Issues (day 1)

 Best Practice
SQL Statements (day 2)
Schema Objects  (day 3) 
PL/SQL Logic (day 3)
Data Warehouse/OLTP (day 3)
    

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 2
Best Practices
SQL Language
Database Objects
PL/SQL
Data Warehouse/OLTP

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 3
SELECT Clause
 Are you selecting more columns than needed?
 Can the number of function calls be reduced or
removed?
 Can the number of procedure calls be reduced or
removed?
 Is the DISTINCT keyword needed?

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 4
FROM Clause
 Table contains the most selective filtering condition
should be placed first, then the next selective
table…
 Divide and Conquer - Use inline view to quickly
eliminate rows from a large table
Move CONNECT BY table to an inline view (dynamic
FROM table)
Hugh performance gain for a multi tables complex SQL

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 5
Divide and Conquer - Use INLINE View
SELECT…
FROM employees emp, AND chg_info.employee_id = deptc.modified_by
employees mgr, AND chg_info.status = 'A'
job_titles jobt, AND rel.node_id = sn.node_id
employee_changes deptc,
AND sn.version_id = (SELECT MAX (version_id)
employees chg_info,
FROM strct_nodes
departments newdept,
WHERE node_id = sn.node_id)
strct_nodes sn,
node_rel rel, AND rel.node_id IN (
status stat SELECT a.node_id
WHERE emp.employee_id_reports_to = mgr.employee_id FROM strct_nodes a
AND emp.status = 'A' WHERE a.version_id = sn.version_id
AND emp.job_title = jobt.job_title_id AND a.date_override IS NULL
AND emp.employee_id = deptc.employee_id START WITH a.node_id = 200000401
AND deptc.new_department_id = newdept.dept_id CONNECT BY a.parent_structure_node_id =
AND deptc.change_type = 'DEPT' PRIOR a.structure_node_id)
AND deptc.change_sequence_number = AND rel.obsolete = 'N'
(SELECT MAX (change_sequence_number) AND rel.status_id = stat.status_id
FROM employee_changes emp2 AND stat.status_name != 'INACTIVE'
WHERE change_type = 'DEPT' AND rel.employee_id = emp.employee_id
AND emp2.employee_id = deptc.employee_id)
Elapsed: 00:53:45.05

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 6
Divide and Conquer - Use INLINE View..
SELECT …
AND deptc.change_sequence_number =
FROM EMPLOYEES emp,
(SELECT MAX(change_sequence_number)
EMPLOYEES mgr, FROM
JOB_TITLES jobt , EMPLOYEE_CHANGES emp2
EMPLOYEE_CHANGES deptc, WHERE change_type = 'DEPT'
EMPLOYEES chg_info,
AND emp2.employee_id = deptc.employee_id)
DEPARTMENTS newdept ,
AND chg_info.employee_id = deptc.modified_by
( SELECT a.node_id, a.version_id
AND chg_info.status = 'A'
FROM strct_nodes a
AND rel.node_id = sn.node_id
WHERE a.date_override IS NULL
AND sn.version_id =
START WITH a.node_id = 200000401
(SELECT MAX(version_id)
CONNECT BY a.parent_structure_node_id =
FROM STRCT_NODES
PRIOR a.structure_node_id
WHERE node_id = sn.node_id)
)sn,
AND rel.obsolete = 'N'
SHR_NODE_REL rel,
AND rel.status_id = stat.status_id
SHR_STATUS stat
AND stat.status_name != 'INACTIVE'
WHERE
AND rel.employee_id = emp.employee_id
emp.employee_id_reports_to =
mgr.employee_id
AND emp.status = 'A'
AND emp.job_title = jobt.job_title_id Elapsed: 00:00:34.00
AND emp.employee_id = deptc.employee_id
AND deptc.new_department_id
=newdept.dept_id
AND deptc.change_type = 'DEPT'
Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 7
WHERE Clause
 Avoid implicit datatype conversion
 Avoid using function on an indexed column
 Avoid comparing column value with NULL
 Outer Join
 Use OR carefully

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 8
Datatype Conversion
 A full table scan is performed on a driving table. Why?

SELECT a.site_use_id, d.address_id


FROM a, b, c, d
WHERE c.customer_number = 12345
AND a.status = 'A' AND b.status = 'A'
AND c.status = 'A' AND d.status = 'A'
AND d.site_use_code = 'BILL_TO'
AND a.address_id = b.address_id
AND b.address_id = d.address_id
AND b.customer_id = c.customer_id
AND d.site_use_id = a.site_use_id

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 9
Datatype Conversion…
 Analysis
c.customer_number is defined as VARCHAR2(50)
A PK index is defined on this column

 Conclusion
Change the filtering condition to
c.customer_number = ’12345’

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 10
Left-hand side column function
 When comparing date value
Instead of:
TRUNC(expected_date) > TRUNC(SYSDATE)
Convert to:
Expected_date >= TRUNC(SYSDATE)+1

Instead of:
TRUNC(transaction_date) = TRUNC(SYSDATE)
Convert to:
transaction_date >= TRUNC(SYSDATE) AND
transaction_date < TRUNC(SYSDATE) + 1

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 11
Compare column value with NULL
 When comparing a column value with NULL, such as:
WHERE Column_name IS NULL

No regular index can be used. A full table scan is


guaranteed.
 Instead, ask yourself the following questions:
Is the column a PK? Therefore, no NULL value can exist

Are there NULL values in the column? If not, no need to


compare with NULL. Can a NOT NULL constraint be added?

Can a DEFAULT VALUE be defined at the column level to


represent NULL value?

Does it make sense to create a bitmap index?

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 12
Using NVL() function
 Instead of using NVL() on a column:
WHERE NVL(region, :input_region) = :input_region

Change to

WHERE region = :input_region
UNION ALL

WHERE region IS NULL

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 13
Use Outer Join Carefully

 Do not use outer join unless absolutely necessary.


Degree of optimizing outer join permutation is VERY
LIMITED
 Instead: Consider using default values in the base
table to avoid outer join
 Do not outer join to a view. This typically results in a
non-mergable view execution plan

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 14
IN VS. EXISTS
 Use IN if the sub-query is more selective
 Use EXISTS if the sub-query is less selective
 Always use NOT EXISTS instead of NOT IN
NOT EXISTS will return rows with NULL value
NOT IN will NOT return rows with NULL value

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 15
Use OR Operator Carefully
 The following SQL statement returns in 43 minutes.
MIC table contains 40 million rows
HTS table contains 85 rows

SELECT mic.inventory_item_id item_id,mic.category_id cat_id


,mic.last_update_date,mic.last_updated_by
,mic.creation_date,mic.created_by
,mic.ges_update_date
,hts.hts_seg1||'.'||hts_seg2||'.'||hts_seg3 hts_number
FROM  mic
      hts
WHERE mic.ORGANIZATION_ID =  1  
AND mic.GLOBAL_NAME = 'US'
AND mic.CATEGORY_SET_ID =  72     
AND hts.category_set_id = 72
AND hts.GLOBAL_NAME     = 'US'
AND hts.category_id = mic.category_id
AND ( mic.ges_update_date > sysdate-10
OR hts.ges_update_date > sysdate-10 );

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 16
Use OR Operator Carefully…
 Analysis
Most selective filter is on ges_update_date column that is
part of the OR condition
Index is defined. However Oracle choose not to use this
index

 Conclusion
Break the SQL statement into 2 SELECTs and joined with a
UNION ALL
SELECT … FROM … WHERE …

mic.ges_update_date > sysdate-10
AND
UNION ALL
SELECT … FROM … WHERE …

AND hts.ges_update_date >sysdate-10


Run time down to 2 seconds

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 17
UNION ALL
 Use UNION ALL whenever possible (no implicit sorts)
 UNION will sort the result set for each SELECT before
combining the final result set
 Remove DISTINCT keyword from SELECT if UNION is
used
 How many rows are returned from the final result set?
Can Oracle memory handle the final result set?
A 6-way UNION statement was taking 860 minutes to complete.

After:
Breaking the statement into 3 UNION ALL statements
Creating 3 Global Temporary Tables (GTTs) to store the intermediate results

Job runtime was reduced to 90 minutes (~90% improvement)

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 18
Large SQL and Oracle Memory
 The larger the SQL statement, the more Oracle
shareable memory allocation (cursor cache and latch
gets)
 Large SQL poses scalability problem
 Shared pool operations are also more expensive in a
RAC environment due to the need to acquire global
cache locks
 SQL statements should not exceed 1 MB in terms of
the amount of sharable memory required:
SELECT sharable_mem, sql_text
FROM v$sql
WHERE sharable_mem > 1000000

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 19
Update Table
 Update is a very expensive operation
 The best Update is NO UPDATE
 Instead of updating millions of rows, do this:
INSERT INTO new_table AS
SELECT <do the update here>
FROM old_table

Point SYNONYM to new_table


or
DROP TABLE old_table
RENAME new_table TO old_table

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 20
Delete all rows from a table

 TRUNCATE table instead of DELETE whenever


possible
DELETE FROM xxxx_REPORT_REV_xxxxx

call count cpu elapsed disk query current rows


------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.01 0.00 0 0 0 0
Execute 1 1.68 737.00 5 2440 21231 9888
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 1.69 737.00 5 2440 21231 9888

 TRUNCATE is a DDL operation, it only shrinks the high


water mark.

Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 21
Presentation_ID © 2006 Cisco Systems, Inc. All rights reserved. Cisco Confidential 22

You might also like