Beruflich Dokumente
Kultur Dokumente
Problems
A Constantly-changing Environment
What affects performance?
Hardware
– Disk space
– RAM
– Network
– CPU
Operating System settings
Database Server parameter settings
Database Design
Indexes on Database Tables
SQL statement
Why SQL statement affecting performance
90%
60%
Performance Problems
According to
40%
industrial
experts
60% of the Others
database’s
performance
problems are
caused by
Application
60%
applications
DBMS Optimize - Find the best way to
process your SQL Statements
Parses
Oracle optimizer
determines the execution path
Binds variables
Executes
How Oracle Optimizer works
Plan 1 Does it try every
Internal rewrite possible way to
& generation of Plan 2 rewrite your SQL?
SQL multiple
Plan 3 Cost
execution plans estimation
Plan 4
Plan 1 cost=1000
How accurate is
Plan 2 cost=3000 the cost estimation?
Plan 3 cost=4000
Plan 4 cost= 500 Execution
Limitations of Optimizer
Limited SQL rewrite
Resource limitation
Cost estimation is only an estimation
Problems too complex for optimizer
Basic Concept of SQL Execution - Driving Path
SELECT *
FROM A, B, C
WHERE A.key1 = B.key1
AND B.key2 = C.key2
AND C.f2 = 0
AND A.f1 = 0
Full B Index
B
Table Scan
Index Scan Full Table
Scan Scan A
A
Specific Tips for writing SQL
Use table join in place of sub-query
If A,B is many to one or one to one relationship
Replace
Select * from A
where A.CITY in
(select B.City from B)
With
Select A.* from A, B
where A.CITY = B.CITY
Joins
Select the smallest table
and/or smallest result set first.
Replace
SELECT * FROM A,B
WHERE A.STATE = B.STATE
With
SELECT * from A
where SALARY +1000 = :NEWSALARY
with
SELECT * from A
where SALARY = :NEWSALARY -1000
Indexed Fields
SELECT * from A
where substr(name, 1, 3) = 'Wil'
Indexed Fields
WHERE clause
Avoid using
SELECT * FROM A
WHERE EMP_SEX || '' = 'm'
Indexed Fields
Do not have default value set to NULL.
If it is a number field and lowest value is 0,
then:
Replace
SELECT * FROM A
WHERE NUMBER IS NOT NULL
with (normally faster response time)
SELECT * FROM A
WHERE NUMBER >0
Index Fields
Replace Outer Join with Union.
If both A.State and B.State have a unique indexed:
Replace
SELECT A.CITY, B.CITY FROM A,B
WHERE A.STATE=B.STATE(+)
With
SELECT A.CITY, B.CITY FROM A,B
WHERE A.STATE=B.STATE
UNION
SELECT NULL, B.CITY FROM B
WHERE NOT EXISTS
(SELECT 'X' FROM A
Where A.STATE=B.STATE)
Optimization Hints
Learn to use optimization hints
Rule Star
First_Row Star_Transformation
All_Rows Index_Combine
Ordered Merge
Use_Hash No_Merge
Use_Concat
No_Expand
Parallel
Driving_Site
ORDER BY clause
Use concatenated index.
If A table is indexed with lastname, firstname.
Replace
SELECT * FROM A
WHERE lastname = 'Smith'
ORDER BY firstname
With
SELECT * FROM A
WHERE lastname = 'Smith'
ORDER BY lastname, firstname
EXIST and IN Sub-query
Assume table A,B relationship is one to many.
SELECT * FROM A
WHERE EXISTS
(SELECT CITY FROM B
WHERE A.CITY = B.CITY)
Use IN Sub-query
SELECT * FROM A
WHERE A.CITY IN
(SELECT B.CITY FROM B)
A.CITY is indexed, B.CITY is not indexed,
and table B has much less rows than A.
SELECT * FROM A
WHERE A.CITY IN
(SELECT B.CITY||’’ FROM B)
A.CITY is indexed, B.CITY is indexed, and
table B has much less rows than A.
Use EXISTS Sub-query
SELECT * FROM A
WHERE EXISTS
(SELECT CITY FROM B
WHERE A.CITY = B.CITY)
A.CITY is not indexed and B.CITY is indexed, and B has more rows
than A.
SELECT * FROM A
WHERE EXISTS
(SELECT CITY FROM B
WHERE A.CITY||’’ = B.CITY)
A.CITY is indexed and B.CITY is indexed, and table B has more rows
than A.
Variables Problem
select * from Employee
where
(Emp_id>:range_lower or :range_lower is null)
and (A.key<:range_upper or :range_upper is null)
select * from A
where (A.key1,A.key2) in
(select B.key1,B.key2 from B
minus
select A.key1,A.key2 from A)
Which SQL is best?
SQL2
Response Time
SQL1
Number of Records
How many ways can you rewrite this statement?
select emp_name,
dpt_name,
grd_desc
from employee,
department DEPARTMENT1,
grade
where emp_grade = grd_id
and emp_dept = dpt_id
and EXISTS (SELECT 'X'
from department DEPARTMENT2
WHERE dpt_avg_salary in (select
min(dpt_avg_salary)
from department DEPARTMENT3)
AND dpt_id =
EMPLOYEE.emp_dept)
1261 semantically equivalent SQL statements
Thank You