Vous êtes sur la page 1sur 40

Oracle Performance Tuning

Tamilselvan G
Be
In ac
Co f o t o n
rp ech
or
at
io
n

-4
ss
a
Cl

Beacon Infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning


Index
1. Aggregate Functions
Rollup
Cube

Analytic Functions
ROW_NUMBER
RANK
DENSE_RANK
COUNT
LEAD
NTILE

3.

SUM
FIRST_VALUE
LAST_VALUE
Ratio_To_Report
LAG
AVG

Most Influential Init.ora Parameters


OPTIMIZER_INDEX_CACHING
OPTIMIZER_INDEX_COST_ADJ

Beacon Infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning


Overview of Rollup and Cube

1. Rollup and Cube

Rollup Details:
ROLLUP's action is straightforward: it creates subtotals which "roll up" from the most
detailed level to a grand total, following a grouping list specified in the ROLLUP clause.
ROLLUP takes as its argument an ordered list of grouping columns. First, it calculates
the standard aggregate values specified in the GROUP BY clause. Then, it creates
progressively higher-level subtotals, moving from right to left through the list of grouping
columns. Finally, it creates a grand total.
CUBE Details:
CUBE takes a specified set of grouping columns and creates subtotals for all possible
combinations of them. In terms of multi-dimensional analysis, CUBE generates all the
subtotals that could be calculated for a data cube with the specified dimensions. If you
have specified CUBE(col1, col2, col3 ), the result set will include all the values that would
be included in an equivalent ROLLUP statement plus additional combinations.
Both the functions were introduced in Oracle 8.1.5

Beacon Infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning

1. Rollup and Cube

Difference between Rollup and Cube


SQL> select * from abc_sales;

SDATE
ST PRODUCT
--------------------- ---------07-MAY-2006 21:27:18 GA TV
06-MAY-2006 21:27:18 GA PHONE
05-MAY-2006 21:27:18 GA PHONE
05-MAY-2006 21:27:18 GA COMP
04-MAY-2006 21:27:18 FL TV
02-MAY-2006 21:27:18 FL PHONE
03-MAY-2006 21:27:18 FL COMP

7 rows selected.

SALES
---------100
40
30
200
200
20
220

SQL> select decode(grouping(state),1,'ALL STATES',STATE),


2
decode(grouping(product),1,'ALL PRODUCTS',PRODUCT),
3
SUM(SALES)
4 from abc_sales group by rollup(state,product)
SQL> /
DECODE(GRO DECODE(GROUP SUM(SALES)
-----------------------------FL
TV
200
FL
COMP
220
FL
PHONE
20
FL
ALL PRODUCTS
440
GA
TV
100
GA
COMP
200
GA
PHONE
70
GA
ALL PRODUCTS
370
ALL STATES ALL PRODUCTS
810

9 rows selected.

Beacon Infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning

1. Rollup and Cube

Difference between Rollup and Cube


SQL> select decode(grouping(state),1,'ALL STATES',STATE),
2
decode(grouping(product),1,'ALL PRODUCTS',PRODUCT),
3
SUM(SALES)
4 from abc_sales group by cube(state,product)
SQL> /

DECODE(GRO DECODE(GROUP
--------------------ALL STATES
ALL PRODUCTS
ALL STATES
TV
ALL STATES
COMP
ALL STATES
PHONE
FL
ALL PRODUCTS
FL
TV
FL
COMP
FL
PHONE
GA
ALL PRODUCTS
GA
TV
GA
COMP
GA
PHONE

SUM(SALES)
---------810
300
------- Extra row
420
------- Extra row
90
------- Extra row
440
200
220
20
370
100
200
70

will
e
w
,
e
b
In cu
l of
a
t
o
t
e
h
get t
ns
nd colum
2
the
n
i
d
e
s
u
n.
o
i
t
c
n
u
cube f

12 rows selected.

Beacon Infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning


Rollup Example
SQL> DESC CUSTOMER
Name
Null?
-------------------------- -------------CUST_ID
NOT NULL
CUST_FNAME
CUST_LNAME

Type
-----------------NUMBER(38)
VARCHAR2(20)
VARCHAR2(20)

SQL> select * from customer;


CUST_ID CUST_FNAME
----------------------------1001
SCOTT
1002
PETER
1003
ELLISON

CUST_LNAME
-------------------TOM
DAVID
BOBBY

SQL> DESC CUST_ORDER


Name
Null? Type
-------------------------- -------- -----------------ORDER_ID
NUMBER(38)
ORDER_DATE
DATE
CUST_ID
NUMBER(38)
ORDER_QTY
NUMBER(38)
SUPPLIED_QTY
NUMBER(38)
ORDER_MESS
CHAR(700)

Beacon Infotech Corporation


www.oracleact.com

1. Rollup and Cube

SQL> select * from cust_order where rownum < 10;


ORDER_ID ORDER_DAT CUST_ID ORDER_QTY SUPPLIED_QTY ORDER_MESS
-------------------------------------------------------1
18_JAN-05
1001
16
5
X
2
17_JAN-05
1001
14
5
X
3
01_JAN-02
1001
20
5
X
4
01_JAN-03
1001
15
5
X
5
01_JAN-04
1001
12
5
X
6
01_JAN-02
1001
17
5
X
7
12_JAN-05
1001
10
5
X
8
01_JAN-03
1001
16
5
X
9
01_JAN-02
1001
13
5
X
..

SQL> select count(*) from cust_order ;


COUNT(*)
---------127,791
SQL> select table_name, blocks, avg_row_len from user_tables
where table_name like 'CUS%' ;
TABLE_NAME
BLOCKS AVG_ROW_LEN
------------------------------------------------------------CUSTOMER
1
19
CUST_ORDER
14200
729
6

2007-11-25

Oracle Performance Tuning


S
Q
L

W
I
T
H
O
U
T

R
O
L
L
U
P

1. Rollup and Cube

select *
from ( select /*+ ordered */
cust_fname, cust_lname, to_char(b.cust_id) as cust,
sum(order_qty) ord_tot, sum(supplied_qty) ord_supp
from cust_order a, customer b
where b.cust_id = a.cust_id
group by cust_fname, cust_lname, to_char(b.cust_id)
UNION
select /*+ Ordered */
'', '', 'Report Total' as cust,
sum(order_qty) ord_tot, sum(supplied_qty) ord_supp
from cust_order a, customer b
where b.cust_id = a.cust_id
)
order by 1 NULLS LAST

CUST_FNAME
-------------------ELLISON
PETER
SCOTT

CUST_LNAME
CUST
-----------------------------------BOBBY
1003
DAVID
1002
TOM
1001
Report Total

# of LIO = 28,409

Beacon Infotech Corporation


www.oracleact.com

ORD_TOT ORD_SUPP
------------------639105
127791
638318
170388
639977
212985
1917400
511164

Elapsed Time = 1.49 Seconds

2007-11-25

Oracle Performance Tuning


S
Q
L

W
I
T
H

R
O
L
L
U
P

1. Rollup and Cube

select *
From (
select decode(grouping(cust_fname),1, '*All First Name', cust_fname) FNAME,
decode(grouping(cust_lname),1, '*All Last Name', cust_lname) LNAME,
decode(grouping(b.cust_id), 1, '*Report Total', b.cust_id) custid,
sum(order_qty) ord_tot,
sum(supplied_qty) ord_supp
from cust_order a,
customer b
where b.cust_id = a.cust_id
group by rollup(cust_fname, cust_lname, b.cust_id)
) c
where (c.custid = '*Report Total' and
c.lname = '*All Last Name' and
c.fname = '*All First Name' ) OR
(c.custid != '*Report Total' )

FNAME
LNAME
CUSTID
-------------------- -------------------- --------------PETER
DAVID
1002
SCOTT
TOM
1001
ELLISON
BOBBY
1003
*All First Name
*All Last Name
*Report Total

ORD_TOT
---------638318
639977
639105
1917400

ORD_SUPP
---------170388
212985
127791
511164

Even though
I reduced the
elapsed time
by half, I am
not satisfied.
Can any one
further
reduce the
elapsed time
by half?

# of LIO = 14,474 Elapsed Time = 0.70 Seconds


Beacon Infotech Corporation
www.oracleact.com

2007-11-25

Oracle Performance Tuning


Overview of Analytic Functions

2. Analytic Functions

One of the coolest things happened in Oracle 8.1.6 was the introduction
of Analytic Function.
Prior to Oracle 8.1.6, Developers wrote complex SQL statements for some
of the following reports:
1. TOP-N Sales Reps by States
2. Ratio to Total
3. Moving Average (Moving Window calculation)
4. Accessing previous and next rows in a group
5. First/Last Row within a Group (Window)
6. Ranking and Percentile
7. Liner Regression Statistics
With the help of new Analytic Functions, today we can write more
scalable application code that not only outperform the old SQL code,
but also solve complex business requirements.

Beacon Infotech Corporation


www.oracleact.com

2007-11-25

Oracle Performance Tuning


How it works

2. Analytic Functions

Example: Slicing the rows into 4 groups


select state, sale_amt, ntile(4) over (order by sum(sale_amt)) ntile4
from ana_sales
group by state, sale_amt
/

Processing Order
Joins, WHERE, GROUP BY and Having

Partitions Created;
Analytic Function applied for each row on
each partition

Final ORDER BY

Output is:
ST SALE_AMT
----------AL
0
FL
10
NY
80
GA
100
NY
120
GA
200
FL
220
GA
300
FL
330
GA
400
FL
450
GA
500
FL
510
NY
910
NY
730

NTILE4
---------1
1
1
1
2
2
2
2
3
3
3
3
4
4
4

15 rows selected.
Beacon Infotech Corporation
www.oracleact.com

10

2007-11-25

Oracle Performance Tuning


How it works
Syntax :

2. Analytic Functions

Analytic_Function(argument1, argument2.)
OVER ( PARTITION clause ORDER BY clause WINDOW clause)

Window Clause

Beacon Infotech Corporation


www.oracleact.com

11

2007-11-25

Oracle Performance Tuning


How it works

2. Analytic Functions

Where
Analytic_Function is the name of the function such MIN, MAX,ROW_NUMBER, RANK,
DENSE_RANK etc.
Arguments can be 0,1,2,3. (No more than 3 arguments is allowed. )

query_partition_clause
Use the PARTITION BY clause to partition the query result set into groups based on one or more
value_expr. If you omit this clause, then the function treats all rows of the query result set as a
single group.

Order_by_clause
Use the order_by_clause to specify how data is ordered within a partition. For all analytic functions
except PERCENTILE_CONT and PERCENTILE_DISC (which take only a single key), you can order
the values in a partition on multiple keys, each defined by a value_expr and each qualified by an
ordering sequence.
Within each function, you can specify multiple ordering expressions. Doing so is especially useful
when using functions that rank values, because the second expression can resolve ties between
identical values for the first expression.

Beacon Infotech Corporation


www.oracleact.com

12

2007-11-25

Oracle Performance Tuning


How it works

2. Analytic Functions

windowing_clause
Some analytic functions allow the windowing_clause.
ROWS | RANGE These keywords define for each row a window (a physical or logical set of rows)
used for calculating the function result. The function is then applied to all the rows in the window.
The window moves through the query result set or partition from top to bottom.
ROWS specifies the window in physical units (rows).
RANGE specifies the window as a logical offset.
You cannot specify this clause unless you have specified the order_by_clause. Some window
boundaries defined by the RANGE clause let you specify only one expression in the
order_by_clause.
The value returned by an analytic function with a logical offset is always deterministic. However,
the value returned by an analytic function with a physical offset may produce nondeterministic
results unless the ordering expression results in a unique ordering. You may have to specify
multiple columns in the order_by_clause to achieve this unique ordering.
BETWEEN ... AND Use the BETWEEN ... AND clause to specify a start point and end point for the
window. The first expression (before AND) defines the start point and the second expression (after
AND) defines the end point.
If you omit BETWEEN and specify only one end point, then Oracle considers it the start point, and the end
point defaults to the current row.
Beacon Infotech Corporation
www.oracleact.com

13

2007-11-25

Oracle Performance Tuning


How it works

2. Analytic Functions

windowing_clause
UNBOUNDED PRECEDING Specify UNBOUNDED PRECEDING to indicate that the window starts at
the first row of the partition. This is the start point specification and cannot be used as an end point
specification.
UNBOUNDED FOLLOWING Specify UNBOUNDED FOLLOWING to indicate that the window ends at
the last row of the partition. This is the end point specification and cannot be used as a start point
specification.
CURRENT ROW As a start point, CURRENT ROW specifies that the window begins at the current
row or value (depending on whether you have specified ROW or RANGE, respectively). In this case
the end point cannot be value_expr PRECEDING.
As an end point, CURRENT ROW specifies that the window ends at the current row or value
(depending on whether you have specified ROW or RANGE, respectively). In this case the start
point cannot be value_expr FOLLOWING.
value_expr PRECEDING or value_expr FOLLOWING For RANGE or ROW:
If value_expr FOLLOWING is the start point, then the end point must be value_expr FOLLOWING.
If value_expr PRECEDING is the end point, then the start point must be value_expr PRECEDING.
If you are defining a logical window defined by an interval of time in numeric format, then you may
need to use conversion functions.
Beacon Infotech Corporation
www.oracleact.com

14

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

FAQ

Frequently asked questions are:


How can I get TOP-N rows by some set of columns?
How can I get 2nd highest paid sales rep in our company?
How can I print total of the report along with each row?
When analytic functions were not available, these questions were
difficult to answer.
Now, Analytic Functions can answer all types of those questions
very easily.

Beacon Infotech Corporation


www.oracleact.com

15

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.1 TOP-N Rows --- Understand the question clearly.


Consider the following request:
ABC corporation had many sales reps in many states and wanted to give bonus to its
top 3 sales reps by state.
This is a ambiguous question because of repeated values, there may be 4 or 5 Sales
Reps who all made same figures. In that situation what shall the developer do?
I can come out with many interpretations with this request:
1.

What Shall I do if all the reps in a state made 0 sales? Can I include those guys in
the report?

2.

List out set of sales reps who made the top 3 sales by state

3.

List out up to 3 people who made the top sales. If 4 or more reps happen to make
the largest sales, the answer would be no rows. If 2 reps make the highest sales
and 2 reps make the same second highest, the answer will be only 2 reps
(highest). Or does the ABC Corp want all 4 reps?

4.

Sort the sales reps by salary from greatest to lowest with in a state. List out the
first 3 reps (or less if less than 3 reps work in a state).

Beacon Infotech Corporation


www.oracleact.com

16

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.1 TOP-N Rows --- Case 1


What Shall I do if all the reps in a state made 0 sales?
I need to know before I start writing a SQL statement. So, let us worry about it now.
SQL> SELECT STATE, ENAME, SALE_AMT FROM ANA_SALES;

1.1 TOP-N Rows - Case 2 List out set of


sales reps who made the top 3
sales by state
Let us build the table.
SQL> desc ana_sales
Name

Null?

Type

------------------- -------- -------------STATE

CHAR(2)

ENAME

VARCHAR2(10)

SALE_AMT

NUMBER(6,2)

SOMETXT1

VARCHAR2(3000)

SOMETXT2

VARCHAR2(3000)

ST ENAME
-- ---------GA Tamil
GA Tom
GA Scott
GA Veera
GA Kumar
FL Bush
FL Gore
FL Ellison
FL Gates
FL Ravi
NY Alex
NY Mike
NY Lux
NY Mary
NY Kristine
AL Ann
AL Arasu
AL Ram
AL Gopi

SALE_AMT
---------100
200
300
400
500
10
220
330
450
510
80
120
730
730
910
0
0
0
0

19 rows selected.
Beacon Infotech Corporation
www.oracleact.com

17

2007-11-25

Oracle Performance Tuning


1.1 TOP-N Rows --- Case 2
SQL> get top-1
1 select *
2 from (select state, ename, sale_amt,
3
dense_rank()
4
over ( partition by state
5
order by sale_amt desc) dr
6
from ana_sales
7
where sale_amt > 0 )
8 where dr <= 3
9* order by state, dr
10 /

Note: For the NY state, we got 4 reps.

2. Analytic Functions
ST ENAME

SALE_AMT

-- ----------

---------

DR
----------

FL Ravi

510

FL Gates

450

FL Ellison

330

GA Kumar

500

GA Veera

400

GA Scott

300

NY Kristine

910

NY Lux

730

NY Mary

730

NY Mike

120

10 rows selected.

Think always in SET in RDBMS

Beacon Infotech Corporation


www.oracleact.com

18

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.1 TOP-N Rows --- Case 3


List out up to 3 people who made the top sales. If 4 or more reps happen to make
the largest sales, the answer would be no rows. If 2 reps make the highest sales
and 2 reps make the same second highest, the answer will be only 2 reps
(highest). Or does the ABC Corp want all 4 reps?
SQL> get top-3

ST ENAME

SALE_AMT

1 select *

-- ----------

----------

FL Ravi

from (select state, ename, sale_amt,

510

CNT
---------1

count(*)

FL Gates

450

over ( partition by state

FL Ellison

330

order by sale_amt desc

GA Kumar

500

range unbounded preceding) cnt

GA Veera

400

from ana_sales

GA Scott

300

where sale_amt > 0 )

NY Kristine

910

9 where cnt <= 3

NY Lux

730

!!!!!

10* order by state, cnt

NY Mary

730

!!!!!

11 /
9 rows selected.
Note: !!!!! Both guys made same sales.

Note: MIKE is gone in this report.


Beacon Infotech Corporation
www.oracleact.com

19

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.1 TOP-N Rows --- Case 4

Sort the sales reps by salary from greatest to lowest with in a state. List
out the first 3 reps (or less if less than 3 reps work in a state).
I updated the sale_amt to 500 for all guys in NY state and see what we get .
SQL> get top-4

ST ENAME

SALE_AMT

RN

1 select *

-- ----------

----------

---------

FL Ravi

510

from (select state, ename, sale_amt,

row_number()

FL Gates

450

over ( partition by state

FL Ellison

330

GA Kumar

500

order by sale_amt desc

) rn

GA Veera

400

from ana_sales

GA Scott

300

where sale_amt > 0 )

NY Alex

500

9 where rn <= 3

NY Mike

500

10* order by state, rn

NY Lux

500

11 /

9 rows selected.

Beacon Infotech Corporation


www.oracleact.com

20

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.2 ROWNUM , RANK , and DENSE_RANK


SQL> select state, ename, sale_amt,
2
dense_rank() over ( partition by state order by sale_amt desc) dr ,
3
rank() over ( partition by state order by sale_amt desc) ra ,
4
row_number() over ( partition by state order by sale_amt desc) rn
5* from ana_sales where sale_amt > 0
6 /

ST ENAME
SALE_AMT DR
RA
RN
-- ------------------------- ------ -------FL Ravi
510
1
1
1
FL Gates
450
2
2
2
FL Ellison
330
3
3
3
FL Gore
220
4
4
4
FL Bush
10
5
5
5
GA Kumar
500
1
1
1
GA Veera
400
2
2
2
GA Scott
300
3
3
3
GA Tom
200
4
4
4
GA Tamil
100
5
5
5
NY Lux
500
1
1
1
NY Mary
500
1
1
2
NY Kristine
500
1
1
3
NY Alex
300
2
4
4
NY Mike
300
2
4
5
15 rows
Beacon
Infotechselected.
Corporation
www.oracleact.com

The difference between RANK


and DENS_RANK:
RANK will skip number if
repeated values are found
within a group.
Dense_Rank will assign
continuous number.

21

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.3 LAG & LEAD - Accessing Previous row and next row

Most useful analytic functions.


SQL> select * from ana_lag_lead ;

RDATE
FAREN
------------------------07-MAY-2006 00:00:00 55
08-MAY-2006 00:00:00 56
09-MAY-2006 00:00:00 52
10-MAY-2006 00:00:00 53
11-MAY-2006 00:00:00 59
12-MAY-2006 00:00:00 50
13-MAY-2006 00:00:00 52
14-MAY-2006 00:00:00 51
15-MAY-2006 00:00:00 45

9 rows selected.

SQL> select rdate, faren,


2
lag(faren) over(order by rdate ) lag,
3
lead(faren) over(order by rdate ) lead
4 from ana_lag_lead
5* order by rdate
SQL> /
RDATE
FAREN LAG
---------------------------07-MAY-2006 00:00:00 55
08-MAY-2006 00:00:00 56
55
09-MAY-2006 00:00:00 52
56
10-MAY-2006 00:00:00 53
52
11-MAY-2006 00:00:00 59
53
12-MAY-2006 00:00:00 50
59
13-MAY-2006 00:00:00 52
50
14-MAY-2006 00:00:00 51
52
15-MAY-2006 00:00:00 45
51

LEAD
----56
52
53
59
50
52
51
45

9 rows selected.

Beacon Infotech Corporation


www.oracleact.com

22

2007-11-25

Oracle Performance Tuning


1.4 AVG and RANGE Average

2. Analytic Functions

Most useful analytic functions.

SQL> select rdate, price,


2
avg(price) over(order by rdate RANGE between 1 preceding and 1 following) range_avg,
3
avg(price) over(order by rdate ROWS between 2 preceding and 2 following) rows_avg,
4
sum(price) over(order by rdate ROWS UNBOUNDED PRECEDING) CUM_SUM
5 from GOLD_PRICE
6* order by rdate
SQL> /

RDATE
-------------------07-MAY-2006 00:00:00
08-MAY-2006 00:00:00
09-MAY-2006 00:00:00
10-MAY-2006 00:00:00
11-MAY-2006 00:00:00
12-MAY-2006 00:00:00
13-MAY-2006 00:00:00
14-MAY-2006 00:00:00
15-MAY-2006 00:00:00

PRICE RANGE_AVG ROWS_AVG CUM_SUM


---------- ------------------------720 725.00
736.67
720
730 736.67
757.50
1450
760 770.00
760.00
2210
820 783.33
780.00
3030
770 803.33
786.00
3800
820 783.33
788.00
4620
760 783.33
772.00
5380
770 756.67
772.50
6150
740 755.00
756.67
6890

9 rows selected.
Beacon Infotech Corporation
www.oracleact.com

23

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.5 FIRST_VALUE and LAST_VALUE


The following example illustrates the use of LAST_VALUE function:

SELECT * FROM T1 ;
EMPLID
PAY_DATE
--------------- ----------A1
31-JAN-2000
A1
28-FEB-2000
A1
31-MAR-2000
A1
31-MAY-2000
B1
B1
B1
C1
C1
C1
C1

31-JAN-2000
31-MAR-2000
31-JUL-2000
31-JAN-2000
28-FEB-2000
31-MAR-2000
31-DEC-2000

D1
31-JAN-2000
D1
31-MAR-2000
D1
31-OCT-2000
14 rows selected.
Beacon Infotech Corporation
www.oracleact.com

select emplid, pay_date,


last_value(pay_date) over
(partition by emplid
order by emplid, pay_date
rows between CURRENT ROW AND UNBOUNDED FOLLOWING) AS lv
from t1 order by emplid, pay_date;
EMPLID
A1
A1
A1
A1

PAY_DATE LV
31-JAN-2000 31-MAY-2000
28-FEB-2000 31-MAY-2000
31-MAR-2000 31-MAY-2000
31-MAY-2000 31-MAY-2000

B1
B1
B1

31-JAN-2000 31-JUL-2000
31-MAR-2000 31-JUL-2000
31-JUL-2000 31-JUL-2000

C1
C1
C1
C1

31-JAN-2000 31-DEC-2000
28-FEB-2000 31-DEC-2000
31-MAR-2000 31-DEC-2000
31-DEC-2000 31-DEC-2000

D1
D1
D1

31-JAN-2000 31-OCT-2000
31-MAR-2000 31-OCT-2000
31-OCT-2000 31-OCT-2000

24

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.6 Ratio To Report


SQL>DESC SALES
Name
Null? Type
------------ -------- --------------------PRODUCT
VARCHAR2(20)
SALES
NUMBER

SQL>SELECT * FROM SALES ;

PRODUCT
SALES
-------------------- ---------P1
280
P2
400
P3
200
P4
300
P5
190
P6
310

Beacon Infotech Corporation


www.oracleact.com

SELECT PRODUCT, SALES ,


TO_CHAR((RATIO_TO_REPORT(SALES) OVER())*100,999.99)
AS SALES_PER
FROM SALES ;

PRODUCT
SALES
-------------------- ---------P1
280
P2
400
P3
200
P4
300
P5
190
P6
310

25

SALES_PER
------16.67
23.81
11.90
17.86
11.31
18.45

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.6 Some Practical Example - Getting 3 consecutive rows


SQL> select * from marks;

NAME
---------DAVID
DAVID
DAVID
DAVID
DAVID
DAVID
DAVID

SCOTT
SCOTT
SCOTT
SCOTT
SCOTT
SCOTT
SCOTT

TEST_DATE
SUBJECT
MARKS
------------------------------------15-JUN-2005 00:00:00 CHEMISTRY
60
15-JUL-2005 00:00:00 CHEMISTRY
30
15-AUG-2005 00:00:00 CHEMISTRY
35
15-SEP-2005 00:00:00 CHEMISTRY
36
15-OCT-2005 00:00:00 CHEMISTRY
62
15-NOV-2005 00:00:00 CHEMISTRY
50
15-DEC-2005 00:00:00 CHEMISTRY
40

15-JUN-2005 00:00:00 CHEMISTRY


15-JUL-2005 00:00:00 CHEMISTRY
15-AUG-2005 00:00:00 CHEMISTRY
15-SEP-2005 00:00:00 CHEMISTRY
15-OCT-2005 00:00:00 CHEMISTRY
15-NOV-2005 00:00:00 CHEMISTRY
15-DEC-2005 00:00:00 CHEMISTRY

Beacon Infotech Corporation


www.oracleact.com

60
70
45
66
62
30
35

MIKE
MIKE
MIKE
MIKE
MIKE
MIKE
MIKE

15-JUN-2005 00:00:00 CHEMISTRY


15-JUL-2005 00:00:00 CHEMISTRY
15-AUG-2005 00:00:00 CHEMISTRY
15-SEP-2005 00:00:00 CHEMISTRY
15-OCT-2005 00:00:00 CHEMISTRY
15-NOV-2005 00:00:00 CHEMISTRY
15-DEC-2005 00:00:00 CHEMISTRY

30
20
35
26
72
40
50

21 rows selected.

School Policy:
The principal of a school declared that
any student scored less than 40 in 3
consecutive months would be declared
Failed in that academic year. He asked
the teacher to prepare a list of students.

26

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.6 Some Practical Example - Getting 3 consecutive rows using count()


1 select distinct name , subject
2 from (
3
select name, subject, test_date, marks,
4
count(fail_ind)
5
over(partition by name, subject order by test_date
6
rows between 2 preceding and current row) as preceding,
7
count(fail_ind)
8
over(partition by name, subject order by test_date
9
rows between current row and 2 following) as following
10
from (
11
select name, subject, test_date, marks,
12
(CASE when marks < 40 then 1 END ) fail_ind
13
from marks)
14
)
15 where preceding = 3 or following = 3
16 /
NAME
---------DAVID
MIKE

SUBJECT
--------CHEMISTRY
CHEMISTRY

Beacon Infotech Corporation


www.oracleact.com

27

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.6 Some Practical Example - Getting 3 consecutive rows using count()


SQL> select name, subject, test_date, marks,
2
count(fail_ind)
3
over(partition by name, subject order by test_date
4
rows between 2 preceding and current row) as preceding,
5
count(fail_ind)
6
over(partition by name, subject order by test_date
7
rows between current row and 2 following) as following
8
from (
9
select name, subject, test_date, marks,
10
(CASE when marks < 40 then 1 END ) fail_ind
11*
from marks)
SQL> /
Let us see the output of the SQL statement.

Beacon Infotech Corporation


www.oracleact.com

28

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.6 Some Practical Example - Getting 3 consecutive rows using count()


NAME
---------DAVID
DAVID
DAVID
DAVID
DAVID
DAVID
DAVID
MIKE
MIKE
MIKE
MIKE
MIKE
MIKE
MIKE
SCOTT
SCOTT
SCOTT
SCOTT
SCOTT
SCOTT
SCOTT

SUBJECT TEST_DATE
----------------CHEMISTRY 15-JUN-05
CHEMISTRY 15-JUL-05
CHEMISTRY 15-AUG-05
CHEMISTRY 15-SEP-05
CHEMISTRY 15-OCT-05
CHEMISTRY 15-NOV-05
CHEMISTRY 15-DEC-05
CHEMISTRY 15-JUN-05
CHEMISTRY 15-JUL-05
CHEMISTRY 15-AUG-05
CHEMISTRY 15-SEP-05
CHEMISTRY 15-OCT-05
CHEMISTRY 15-NOV-05
CHEMISTRY 15-DEC-05
CHEMISTRY 15-JUN-05
CHEMISTRY 15-JUL-05
CHEMISTRY 15-AUG-05
CHEMISTRY 15-SEP-05
CHEMISTRY 15-OCT-05
CHEMISTRY 15-NOV-05
CHEMISTRY 15-DEC-05

MARKS PRECEDING FOLLOWING


---------- ------------------60
0
2
30
1
3
35
2
2
36
3
1
62
2
0
50
1
0
40
0
0
30
1
3
20
2
3
35
3
2
26
3
1
72
2
0
40
1
0
50
0
0
60
0
0
70
0
0
45
0
0
66
0
1
62
0
2
30
1
2
35
2
1

21 rows selected.

Beacon Infotech Corporation


www.oracleact.com

29

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.6 Some Practical Example - Getting 3 consecutive rows using lag and lead
1 select distinct name, subject
2 from (
3
select name, subject, test_date, marks,
4
lag(marks,1) over (partition by name, subject order by test_date) pr_marks,
5
lag(marks,2) over (partition by name, subject order by test_date) pr_to_pr_marks,
6
lead(marks,1) over (partition by name, subject order by test_date) ne_marks,
7
lead(marks,2) over (partition by name, subject order by test_date) ne_to_ne_marks
8
from marks
9
)
10 where (marks < 40 and pr_marks < 40 and pr_to_pr_marks < 40)
11
OR
12
(marks < 40 and ne_marks < 40 and ne_to_ne_marks < 40)
13 /

NAME
---------DAVID
MIKE

SUBJECT
--------CHEMISTRY
CHEMISTRY

Beacon Infotech Corporation


www.oracleact.com

30

2007-11-25

Oracle Performance Tuning

2. Analytic Functions

1.7 Other Functions available


1.

CUME_DIST - The CUME_DIST function (defined as the inverse of percentile in some


statistical books) computes the position of a specified value relative to a set of values. The
order can be ascending or descending. Ascending is the default. The range of values for
CUME_DIST is from greater than 0 to 1. To compute the CUME_DIST of a value x in a set S
of size N, you use the formula:

PERCENT_RANK - PERCENT_RANK is similar to CUME_DIST, but it uses rank values


rather than row counts in its numerator. Therefore, it returns the percent rank of a value
relative to a group of values. The function is available in many popular spreadsheets.
PERCENT_RANK of a row is calculated as:
(rank of row in its partition - 1) / (number of rows in the partition - 1)
3
Linear Regression Functions
The regression functions support the fitting of an ordinary-least-squares regression line to a set of
number pairs. You can use them as both aggregate functions or windowing or reporting
functions.
The functions are as follows:
REGR_COUNT Function , REGR_AVGY and REGR_AVGX Functions
REGR_SLOPE and REGR_INTERCEPT Functions , REGR_R2 Function
REGR_SXX, REGR_SYY, and REGR_SXY Functions
4. A LOT OF STATISTICAL Functions MEDIAN, STATS_MOD, ANOVA, COVAR, STD_DEV etc
Beacon Infotech Corporation
www.oracleact.com

31

2007-11-25

Oracle Performance Tuning

3. Most Influential Init.ora Parameters

OPTIMIZER_INDEX_CACHING and OPTIMIZER_INDEX_COST_ADJ are the most important


parameters among all the init.ora parameters. The Cost based optimizer extensively uses
these 2 parameters values during the cost calculation for arriving the optimum execution
plan.
Depending upon the type of the work (OLTP, DSS , DW) , you can change these values either at the
instance level or at the session level, and the impact is highly visible.
Oracle Database Performance Tuning Guide 10g Release 2 (10.2) Part Number B14211-01
OPTIMIZER_INDEX_CACHING
This parameter controls the costing of an index probe in conjunction with a nested loop. The
range of values 0 to 100 for OPTIMIZER_INDEX_CACHING indicates percentage of index
blocks in the buffer cache, which modifies the optimizer's assumptions about index caching
for nested loops and IN-list iterators. A value of 100 infers that 100% of the index blocks are
likely to be found in the buffer cache and the optimizer adjusts the cost of an index probe or
nested loop accordingly. Use caution when using this parameter because execution plans
can change in favor of index caching.
OPTIMIZER_INDEX_COST_ADJ
This parameter can be used to adjust the cost of index probes. The range of values is 1 to 10000.
The default value is 100, which means that indexes are evaluated as an access path based on
the normal costing model. A value of 10 means that the cost of an index access path is onetenth the normal cost of an index access path.

Beacon Infotech Corporation


www.oracleact.com

32

2007-11-25

Oracle Performance Tuning

3. Most Influential Init.ora Parameters

It is very easy to understand the impact of the first parameter, OPTIMIZER_INDEX_CACHING. It


tells the optimizer what percentage of index blocks are available in the buffer cache. And it
directly affects the cost calculation.
However, the 2nd parameter, OPTIMIZER_INDEX_COST_ADJ confuses many DBAs and
developers because the range of values accepted is 1 through 10000. Many experts interpret
the meaning in a different way. Any change in OPTIMIZER_INDEX_COST_ADJ results in
table access cost being scaled down (up) to the current value divided by 100.
In other words, I would say, if the value is less than 100, then the Optimizer may choose
indexed access path OR if the value is equal to 100 (or greater than 100), then Optimizer
may choose FULL TABLE SCAN access path.
You can also interpret the meaning in this way: low value for OPTIMIZER_INDEX_COST_ADJ
indicates single block read time is cheaper; high value for OPTIMIZER_INDEX_COST_ADJ
indicates single block read time costlier.
<..Optimizer_Index_Cost_Adj values ..>
1.10..20..30....100200..50010004000.800010000
<Consider Index Access >

<Consider FULL TABLE SCAN >

Note:
If OPTIMIZER_INDEX_CACHING is for index blocks, then
OPTIMIZER_INDEX_COST_ADJ is for table blocks available in the buffer cache.
Beacon Infotech Corporation
www.oracleact.com

33

2007-11-25

Oracle Performance Tuning

3. Most Influential Init.ora Parameters


SQL> desc state
Name
Null?
Type
--------------------------------------------STATEID
NOT NULL
CHAR(2)
NAME
VARCHAR2(30)
SOMETXT
VARCHAR2(3900)
SQL> select stateid, name from state ;
ST NAME
-- -----------------------------GA Georgia
CA California
NY Newyork
AL Alabama
TX Texas
MA Massachucsetts
SC South Carolina
NC North Carolina
AZ Arizona
9 rows selected. ------------ Small Table to filter rows
based on the STATE code
Note: All the tests are done in 9i. You may get different
execution plans in your system because the cost is
affected by many parameters settings.

Among the 2 parameters, Optimizer_Index_Cost_Adj is


more aggressive than OPIMIZER_INDEX_CACHING.
First let us set up 2 tables to test the theory.
SQL> desc sales
Name
Null?
Type
----------------------------------------CUST_ID
NOT NULL
NUMBER(12)
STATE
NOT NULL
CHAR(2)
SALE_YEAR
NUMBER(4)
SALE_MONTH
NUMBER(2)
PROD_ID
NUMBER
QTY
NUMBER
AMT
NUMBER
COMM_1
VARCHAR2(50)
COMM_2
VARCHAR2(200)

SQL> select /*+ full(a) parallel(a,16) */ count(*) from sales a ;


COUNT(*)
---------14,336,064 ----------- Big table to test different values.

Beacon Infotech Corporation


www.oracleact.com

34

2007-11-25

Oracle Performance Tuning

3. Most Influential Init.ora Parameters

Case 1
Let us first see what will be the cost for a query with default values of 0 and 100 for
optimizer_index_caching and optimizer_index_cost_adj respectively.
SQL> alter session set optimizer_index_caching = 0;
Session altered.
SQL> alter session set optimizer_index_cost_adj = 100 ;
Session altered.
SQL> explain plan for
2 select a.cust_id , b.name
3 from sales a, state b
4 where a.state = b.stateid and b.stateid = 'GA' ;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost |
----------------------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT

| 573K |

15M | 45551 |

| 1 | NESTED LOOPS

| 573K |

15M | 45551 |

| 2 | TABLE ACCESS BY INDEX ROWID | STATE

21

|* 3 |

| STATE_PK

| SALES

| 573K | 4480K | 45550 |

INDEX UNIQUE SCAN

|* 4 | TABLE ACCESS FULL

|
|

|
|

--------------------------------------------------------------------------------------------------------------------Beacon Infotech Corporation


www.oracleact.com

35

So, the total cost


of the query is
45,551 IO. Note
also that when
CPU costing is
off, then the
COST is nothing
but total number
of IO.
This is our base
line data that will
be compared
with the
remaining tests.
2007-11-25

Oracle Performance Tuning

3. Most Influential Init.ora Parameters

Case 2
I changed the OPTIMIZER_INDEX_COST_ADJ to 10 but kept the default value for OPTIMIZER_INDEX_CACHING.
SQL> alter session set optimizer_index_caching = 0 ;
Session altered.
SQL> alter session set optimizer_index_cost_adj = 10 ;
Session altered.
SQL> explain plan for
select a.cust_id , b.name from sales a, state b
where a.state = b.stateid and
b.stateid = 'GA' ;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT
|
| 573K| 15M | 37683 (1) |
| 1 | NESTED LOOPS
|
| 573K| 15M | 37683 (1) |
| 2 | TABLE ACCESS BY INDEX ROWID | STATE
| 1 | 21
| 2 (50) |
|* 3 | INDEX UNIQUE SCAN
| STATE_PK
| 1 |
|
|
| 4 | TABLE ACCESS BY INDEX ROWID | SALES
| 573K | 4480K | 37682 (1) |
|* 5 | INDEX RANGE SCAN
| SALES_IDX_2 | 573K |
| 30095 (0) |
------------------------------------------------------------------------------------------------------------------------------------------

The Query plan is completely changed from full table scan to indexed access on the SALES
table. The total cost of the query came down to 37,683 from 45,551, the TABLE ACCESS BY
INDEX ROWID cost is 37,682 that includes the cost of INDEX RANGE SCAN for
SALES_IDX_2 30,095.
Beacon Infotech Corporation
www.oracleact.com

36

2007-11-25

Oracle Performance Tuning

3. Most Influential Init.ora Parameters

Case 3
In real life situation some amount of index leaf blocks are always cached in the
memory.
Now I tell Oracle that 50 % of index blocks are cached in the SGA by changing the
OPTIMIZER_INDEX_CACHING parameter.

SQL> alter session set optimizer_index_caching = 50 ;


Session altered.
SQL> alter session set optimizer_index_cost_adj = 10 ;
Session altered.
SQL> explain plan for
2 select a.cust_id , b.name
3 from sales a, state b
4 where a.state = b.stateid and b.stateid = 'GA' ;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT
|
| 573K| 15M | 36207 (0) |
| 1 | NESTED LOOPS
|
| 573K| 15M | 36207 (0) |
| 2 | TABLE ACCESS BY INDEX ROWID | STATE
| 1 | 21
| 2 (50) |
|* 3 | INDEX UNIQUE SCAN
| STATE_PK
| 1 |
|
|
| 4 | TABLE ACCESS BY INDEX ROWID | SALES
| 573K| 4480K | 36206 (0) |
|* 5 | INDEX RANGE SCAN
| SALES_IDX_2 | 573K|
| 15344 (0) |
--------------------------------------------------------------------------------------------------------------------------Beacon
Infotech Corporation
www.oracleact.com

37

In Case -2 , the cost


for INDEX RANGE
SCAN for
SALES_IDX_2 was
30095, after
changing the
parameter
OPTIMIZER_INDEX_
CACHING to 50, it
came to 15344, just
half of what it was
before.
The TABLE
ACCESS BY INDEX
ROWID for SALES
table came down to
36206 from 37682.
Finally the total
cost came down to
36,207 from 37,683.

2007-11-25

Oracle Performance Tuning

3. Most Influential Init.ora Parameters

Case 4
If you further increase the parameter OPTIMIZER_INDEX_CACHING, then the cost of INDEX SCAN will further
come down.
Let us test this concept with a new value, 90.
SQL> alter session set optimizer_index_caching = 90 ;
Session altered.
SQL> alter session set optimizer_index_cost_adj = 10 ;
Session altered.
SQL> explain plan for
2 select a.cust_id , b.name
3 from sales a, state b
4 where a.state = b.stateid and b.stateid = 'GA' ;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT
|
| 573K | 15M | 34980 (0) |
| 1 | NESTED LOOPS
|
| 573K | 15M | 34980 (0) |
| 2 | TABLE ACCESS BY INDEX ROWID | STATE
| 1 | 21
| 2 (50) |
|* 3 | INDEX UNIQUE SCAN
| STATE_PK
| 1 |
|
|
| 4 | TABLE ACCESS BY INDEX ROWID | SALES
| 573K | 4480K | 34979 (0) |
|* 5 | INDEX RANGE SCAN
| SALES_IDX_2 | 573K |
| 3069 (0) |
-------------------------------------------------------------------------------------------------------------------------------------The cost of INDEX RANGE SCAN has been reduced to 3069.

Beacon Infotech Corporation


www.oracleact.com

38

2007-11-25

Oracle Performance Tuning

3. Most Influential Init.ora Parameters

In conclusion
When the SYSTEM statistics is off:
One thing you should remember, the above tests and various costs obtained did not
tell you which query will run faster.
I just demonstrated the impact of changing those 2 parameters.
There is no rule of thumb to fix those 2 values. How ever, One thing is sure that the
default value 0 and 100 for OPTIMIZER_INDEX_CACHING and
OPTIMIZER_INDEX_COST_ADJ respectively are set for Data Warehouse System.
If your system is OLTP, then these 2 parameters values should be changed. I would
test the sytem with different values before choosing the correct values.
Setting 90 to OPTIMIZER_INDEX_CACHING and 10 (or 15) to
OPTIMIZER_INDEX_COST_ADJ will perform good for OLTP system.
When the SYSTEM statistics is on:
Starting from 9i and 10g You can collect system statistics (CPU & IO). When those
statistics are available, then the optimizer uses those statistics in the execution
plan and ignores OPTIMIZER_INDEX_CACHING and
OPTIMIZER_INDEX_COST_ADJ values.
Beacon Infotech Corporation
www.oracleact.com

39

2007-11-25

Oracle Performance Tuning

Beacon Infotech Corporation


www.oracleact.com

40

2007-11-25

Vous aimerez peut-être aussi