You are on page 1of 41

SQL Performance Tuning Tips

Tuning Tips and Techniques w Oracles SQL is a very flexible language.


You can use many different SQL statements to accomplish the same purpose. w Yet, although dozens of differently constructed ueries and retrieval statements can produce the same result, in a given situation only one statement !ill be the most efficient choice.

w w "t is much harder to !rite efficient SQL than it is to !rite functionally correct SQL w w # SQL choice is correct only if it produces the right result in the shortest possible amount of time, !ithout impeding the performance of any other system resources.

w w
3

Sharing SQL Statements


w $arsing a SQL statement and figuring out its optimal execution plan are time%consuming operations, Oracle holds SQL statements in memory after it has parsed them w &henever you issue a SQL statement, Oracle first loo's in the context (S)#* area to see if there is an identical statement there w +o be shared, the SQL statements must truly be the same w
4

w ,or example the follo!ing t!o select statements are -O+ the same. w

S/L/0+ S+12/-+3-45/6, -#4/ ,6O4 S+12/-+ &7/6/ S+12/-3-145/6 8 9::9

Select Student3-umber, -ame ,rom Student &here Student3-umber 8 ;9::9

Using Bind variables when possible


w +ry using 5ind <ariable instead of Literals. 0onsider the follo!ing SQL statement =
S/L/0+ ,"6S+3-#4/, L#S+3-#4/ ,6O4 0lient &7/6/ 0L"/-+3-14 8 >:99

w Since the 0L"/-+3-145/6 is li'ely to be different for every execution, !e !ill almost never find a matching statement in the Shared $ool and conse uently the statement !ill have to be reparsed every time w 0onsider the follo!ing approach = w
S/L/0+ ,"6S+3-#4/, L#S+3-#4/ ,6O4 0lient &7/6/ 0L"/-+3-14 8 :Client_Num

w You do not need to create a ne! cursor or re%parse the SQL statement if the value of the bind variable changes. #lso, if another session executes the same statement, it is li'ely to find them in the Shared $ool, since the name of the bind variable does not change from execution to execution. w
6

Using ROWI

When !ossible

w /ach record added to the database has a uni ue 6O&"2 and !ill never change until the delete statement issued on that record. w "f the record bloc' or location !as changed for any reason, the original 6O&"2 points to the ne! location or the ne! 6O&"2 and so on. w 1se 6O&"2 !henever possible to get the best performance out of your retrievals

w
7

cursor accounts3cur is select acct3no, currency, branch 6o!id acct3ro!id, ,rom account !here . . . . for acct3rec in accounts3cur loop update account set !here ro!id 8 acct3rec.acct3ro!id? end loop?

1sing &7/6/ in $lace of 7#<"-)


w "n general, avoid including a 7#<"-) clause in the S/L/0+ statements. +he 7#<"-) clause filters selected ro!s only after all ro!s have been fetched. +his could include sorting, summing, and etc. 7#<"-) clause w usually used to filter a S/L/0+ statement containing group functions. select @ from account !here cust3#ctive3flag 8 y having group 8 99> "nstead use % select @ from account !here cust3#ctive3flag 8 y and group 8 99> w
9

Using U"IO" #LL instead o$ U"IO"


w +he SO6+ operation is very expensive in terms of 0$1 consumption. w +he 1-"O- operation sorts the result set to eliminate any ro!s, !hich are !ithin the sub% ueries. w 1-"O- #LL includes duplicate ro!s and does not re uire a sort. 1nless you re uire that these duplicate ro!s be eliminated, use 1-"O- #LL w

Using NOT EXISTS in place of NOT IN for indexed columns


w "n sub% uery statements such as the follo!ing, the -O+ "clause causes an internal sortAmerge. select @ from Student !here S+12/-+3-14 not in (select S+12/-+3-14 from 0L#SS* w So use% select @ from S+12/-+ 0 !here not exists (select > from 0L#SS # !here #.S+12/-+3-14 8 0.S+12/-+3-14*
11

Using IN with MINUS in place of NOT IN for non indexed columns


w "n sub% uery statements such as the follo!ing, the -O+ "- clause causes an internal sortAmerge select @ from system3user !here su3user3id not in (select ac3user from account* w "-S+/#2 1S/ select @ from system3user !here su3user3id in (select su3user3id from system3user minus select ac3user from account*

w
12

Using Joints in Place of EXISTS for Uni ue Scan Indexes and small ta!les
w "n general Boin tables rather than specifying sub% ueries for them such as the follo!ing.

8 w &ith Boin %

select acct3"2, currency, branch from account !here exists (select > from branch !here code branch and def3curr 8 C99>C* select acct3"2,currency, branch from account #, branch 5 !here b.code 8 #.branch and #.def3curr 8 C99>C
13

Influencing the Optimizer using HINTS


w 7ints are special instructions to Optimizer. You can change the Optimization goal for an individual statement by using 7int. Some commonly used 7ints are. 07OOS/, 61L/, ,1LL(table3name*, "-2/D(table3name index3name*, 1S/3-L, 1S/37#S7(table3name*, $#6#LL/L(table3name parallelism* etc. w S/L/0+ /*+RUL */ -#4/, #00+3#LLO0#+"O-3$/60/-+#)/ ,6O4 #00O1-+S &7/6/ #00O1-+3"2 8 >:99 w +he above SQL statement !ill be processed using the 61L/ based optimizer. S/L/0+ /*+ IN! "#$% $CCT_I!_IN!& */ -#4/, #00+3#LLO0#+"O-3$/60/-+#)/ ,6O4 #00O1-+S # &7/6/ #00O1-+3"2 8 :$CCT_I! #-2 0L"/-+3"28 :CLI NT_I! w "n the above SQL statement, an "ndex 7int has been used to force the use of a particular index. w
14

Using Inde%es to Improve !er$ormance


w "ndexes primarily exist to enhance performance. 5ut they do not come !ithout a cost. "ndexes must be updated during "-S/6+, 1$2#+/ and 2/L/+/ operation, !hich may slo! do!n performance w 5esides, the usefulness of an "ndex depends on selectivity of a columnAcolumns. w )enerally "ndexes are more selective if the columnAcolumns have a large number of uni ue values. w "f an "ndex contains more than one column, it is called 0O-0#+/-#+/2 "-2/D ! w 0oncatenated index is often more selective than a single 'ey index. w 0olumn positions play an important role in 0oncatenated index. &hile using 0oncatenated "ndex, be sure to use L/#2"-) columns
15

"hich is #aster$ Indexed %etrie&al or #ull'ta!le Scan(


w ,ull%table scans can be efficient because they re uire little dis' movement. +he dis' starts reading at one point and continues reading contiguous data bloc's. w "ndex retrievals are usually more efficient !hen retrieving fe! records or !hen using Boints !ith other tables. w "f more than >:E, this percentage defers from table to table and depends on the physical I/O, of the table retrieved a full table scan is better.

16

)&oiding *alculations on Indexed


w +he optimizer does not use*olumns an index if the indexed column is a part of a function (in the &7/6/ clause*. "n general, avoid doing calculations on indexed columns, apply function and concatenating on an indexed columns. Select @ from #ccount &here substr(ac3acct3no,>,>* 8 > "nstead use % Select @ from #ccount &here ac3acct3no li'e >E Note : The SQL functions MIN and MAX are exceptions to this rule and will utilize all available indexes.
17

)&oiding NOT on Indexed *olumns


w "n general avoid using -O+ !hen testing indexed columns! w w &hen Oracle encounters a -O+, it !ill choose not to use index and !ill perform a full%table scan instead. w Remember, indexes are built on !hat is in a table, but not !hat is -O+ in a table. w ,or example the follo!ing select statement !ill never use the index on STU! NT_NU' column Select @ from student &here S+12/-+3-14 not li'e FE

18

Using UNION in Place of O%


w "n general, al!ays consider the 1-"O- verb instead of O6 verb in the &7/6/ clauses. w w 1sing O6 on an indexed column causes the optimizer to perform a full%table scan rather than an indexed retrieval. w w

19

PositionofJoinsintheWHEREClause
w Ta"#e $oins s%ou#& "e 'ri((en firs( "efore an) con&i(ion of *+,-, c#ause! .n& (%e con&i(ions '%ic% fi#(er ou( (%e ma/imum recor&s s%ou#& "e p#ace& a( (%e en& af(er (%e $oins as (%e parsing is &one from 01TT12 (o T1P! w Leas( ,fficien( 3 w S,L,4T ! ! ! !

5-12 ,2P , *+,-, S.L 6 5 .78 910 : 4L,-; .78 25 < =S,L,4T 41>7T=?@ 5-12 ,2P *+,-, 2A- : ,!,2P71@B
2

w w 2os( ,fficien( 3
w

S,L,4T ! ! ! ! 5-12 ,2P , *+,-, 25 < =S,L,4T 41>7T=?@ 5-12 ,2P *+,-, 2A- : ,!,2P71 @ .78 S.L 6 5 .78 910 : 4L,-;B

21

Side by Side Comparison of Join Methods


w Join w "hen can !e used$ #n& 'oin (qui 'oins onl& complete cluster )e& o$ clustered
tables only

Nested +oops Join

Sort'Merge Join

,ash Join

*luster

(qui 'oins onl&

(qui 'oins on

w w

Optimi-er hint$

use*nl

Use*merge

use*hash

"one

%esource concerns$ +!U Temporar& segments ,emor& Storage is) I-O init.ora parameters$"one sort*area*si.e hash*'oin*enabled "one db*$ile*multi bloc)* hash*area*si.e
read3count hash3multibloc'3io3count

#eatures$Wor)s with an& 'oin Better than nested Better than nested Reduces I-O $or master/ loop when inde% is loop when inde% is detail Queries missing or search missing or search critiria is not restrictive criteria is not restrictive /raw!ac0s$ 0er& ine$$icient ,ust per$orm an e%tra sort +an require lots +lustered data can ta)e when no suitable +annot return $irst o$ memor&more space to store inde% e%ist rows quic)l& slows down updates and $ull scan

22

w 1-.4L, parser a#'a)s processes (a"#e names from rig%( (o #ef(C so (%e (a"#e name )ou specif) #as( =&riDing (a"#e@ is ac(ua##) (%e firs( (a"#e processe&! w Ef )ou specif) more (%an one (a"#e in a 5-12 c#ause of a S,L,4T s(a(emen(C )ou mus( c%oose (%e (a"#e con(aining (%e #o'es( num"er of ro's as (%e &riDing (a"#e! w *%en 1-.4L, processes mu#(ip#e (a"#esC i( uses an in(erna# sor(Fmerge proce&ure (o $oin (%ose (a"#es! w 5irs(C i( scans an& sor(s (%e firs( (a"#e =(%e one specifie& #as( in (%e 5-12 c#ause@! w 7e/(C i( scans (%e secon& (a"#e =(%e one prior (o (%e #as( in (%e 5-12 c#ause@ an& merges a## of (%e ro's re(rieDe& from (%e secon& (a"#e 'i(% (%ose re(rieDe& from (%e firs( (a"#e! w 5or e/amp#e3 Ta"#e T.0. %as 16C384 ro's! Ta"#e T.00 %as 1 ro'! S,L,4T 41>7T=?@ 5-12 T.0.C T.00 !96 secon&s e#apse&
S,L,4T 41>7T=?@ 5-12 T.00C T.0. e#apse& 26! 9 secon&s
23

w Ef (%ree (a"#es are "eing $oine&C se#ec( (%e in(ersec(ion (a"#e as (%e &riDing (a"#e! w T%e in(ersec(ion (a"#e is (%e (a"#e (%a( %as man) (a"#es &epen&en( on i(! w ,!g!! T%e ,2P (a"#e represen(s (%e in(ersec(ion "e('een (%e L14.TE17 (a"#e an& (%e 4.T,A1-G (a"#e! S,L,4T ! ! ! 5-12 L14.TE17 LC 4.T,A1-G 4C ,2P , *+,-, ,!,2PH71 0,T*,,7 1 .78 2 .78 ,!4.TH71 : 4!4.TH71 .78 ,!L147 : L!L147 is more efficien( (%an (%is ne/( e/amp#e3 S,L,4T ! ! ! 5-12 ,2P ,C L14.TE17 LC 4.T,A1-G 4 *+,-, ,!4.TH71 : 4!4.TH71 .78 ,!L147 : L!L147 .78 ,!,2PH71 0,T*,,7 1 .78 2

24

Pro!lems when *on&erting Index *olumn T1pes


w Oracle performs simple column type conversion, or casting, !hen it compares columns of different type. "f a numeric column is compared to an alphabetic column, the character column automatically has its type converted to numeric.
Select @ from #ccount &here #00O1-+3"2 8 F9G:H99> "n fact, because of conversion this statement !ill actually be processed as. Select @ from #ccount &here to3number(#00O1-+3"2* 8 F9G:H99>
25

w 5ut the follo!ing statement. Select @ ,rom acc3txn &here acc3txn3ref3no 8 >>FFF99>:IF9 w &ill be processed as. Select @ ,rom acc3txn &here acc3txn3ref3no to3number(>>FFF99>:IF9 *

26

Use DECODE to Reduce Processing


w The DECODE statement provides a wa to avoid havin! to scan the same rows repetitivel or to "oin the same table repetitivel . w For example: SELECT CO#$T%&'( S#)%S*L' +,O) E)./E,E DE-T0$O 1 2232 *$D E$*)E L45E 6S)4T/789 SELECT CO#$T%&'( S#)%S*L' +,O) E)./E,E DE-T0$O 1 22:2 *$D E$*)E L45E 6S)4T/789 w ;ou can achieve the same result much more efficientl DECODE< with

27

SELECT CO#$T%DECODE%DE-T0$O(2232( 6=8( $#LL'' D22320CO#$T( CO#$T%DECODE%DE-T0$O(22:2(6=8($#LL'' D22:20CO#$T( S#)%DECODE%DE-T0$O(2232( S*L( $#LL'' D22320S*L( S#)%DECODE%DE-T0$O( 22:2( S*L( $#LL'' D22:20S*L +,O) E)./E,E E$*)E L45E 6S)4T/789 w Similarl ( DECODE can be used in !" clause effectivel . w ROUP !" or ORDER

w
28

w To improve performance( minimize the number of table loo>ups in ?ueries( particularl if our statements include sub@?uer SELECTs or multi@column #-D*TEs. For example: #east E$$icient : SELECT T*A0$*)E +,O) T*ALES ./E,E T*A0$*)E 1 %%E#EC& T*A0$*)E +,O) T*A0COL#)$S ./E,E BE,S4O$ 1 C2D' *$D DA0BE, 1 %%E#EC& DA0BE, +,O) T*A0COL#)$S ./E,E BE,S4O$ 1 C2D'

29

Most E$$icient :
SELECT T*A0$*)E +,O) T*ALES ./E,E %T*A0$*)E(DA0BE,'1 %SELECT T*A0$*)E( DA0BE, +,O) T*A0COL#)$S ./E,E BE,S4O$ 1 C2D'

Use EXI%&% in Place o$ DI%&INC&


w *void "oins that re?uire the D4ST4$CT ?ualifier on the SELECT list when ou submit ?ueries used to determine information at the owner end of a one@to@man relationship %e.!. departments that have man emplo ees'. #east E$$icient : SELECT DI%&INC& DE-T0$O( DE-T0$*)E +,O) DE-T D( E)- E ./E,E D.DE-T0$O 1 E.DE-T0$O Most E$$icient : SELECT DE-T0$O( DE-T0$*)E +,O) DE-T D ./E,E EXI%&% %SELECT 6=8 +,O) E)- E ./E,E E.DE-T0$O 1 D.DE-T0$O'9 w E=4STS is a faster alternative because the ,DA)S >ernel realizes that when the sub@?uer has been satisfied once( the ?uer can be terminated. 31 w

Some

o1s and

on1ts

w Some S/L/0+ statement &7/6/ clauses do not use indexes at all. "f you have specified an index over a table that is referenced by a clause of type sho!n in this section Oracle !ill simply ignore the index! w ,or each clause that cannot use an index, an alternative approach, !hich !ill allo! you to get better performance out of your S/L/0+ statements is suggested.
w

32

w Do Not Use: Use Select @ from #ccount &here substr(ac3acct3no,>,>* 8 F w Use: Select @ from #ccount &here ac3acct3no li'e FE w Do Not Use: Select @ ,rom fin3trxn &here ft3trxn3ref3no J8 9 w Use: Select @ ,rom fin3trxn &here ft3trxn3ref3no K 9
33

Do Not Use: Select @ ,rom account &here ac3type LL ac3branch 8 sav99> Use: Select @ ,rom account &here ac3type 8 sav #nd ac3branch 8 sav99> Do Not Use: Select @ ,rom 0L"/-+ !here to3char(01++3O,,3+"4/,yyyymmdd* 8 to3char(sysdate,yyyymmdd* Use: Select @ ,rom 0L"/-+ &here 01+3O,,32#+/ K8 trunc(sysdate* and 01+3O,,3+"4/ M trunc(sysdate* N >
34

w w Do Not Use: w Select @ ,rom acct3trxn &here to3char(at3value3date,yyyymmdd* K to3char(sysdate,yyyymmdd* w Use: Select @ ,rom acct3trxn &here at3value3date K8 trunc(sysdate* N >

35

w w Do Not Use: Select @ ,rom acct3trxn &here to3char(at3value3date,yyyymmdd* M to3char(sysdate,yyyymmdd* w Use: Select @ ,rom acct3trxn &here at3value3date M trunc(sysdate* w

36

w w Do Not Use: Select @ ,rom acct3trxn &here to3char(at3value3date,yyyymmdd* K8 to3char(sysdate,yyyymmdd* w Use: Select @ ,rom acct3trxn &here at3value3date K8 trunc(sysdate*

w
37

w w Do Not Use: Select @ ,rom acct3trxn &here to3char(at3value3date,yyyymmdd* to3char(sysdate,yyyymmdd* w Use: Select @ ,rom acct3trxn &here at3value3date M trunc(sysdate* N > w Do Not Use: Select count( @* ,rom 56OO/6 w Use:

M8

Select count($6"4#6Y3O/Y or a non null "-2/D column or > * ,rom 5ro'er


38

AvoidUsingSELECT*Clauses
w T%e &)namic SQL co#umn reference =?@ giDes )ou a 'a) (o refer (o a## of (%e co#umns of a (a"#e! w w 8o no( use (%e ? fea(ure "ecause i( is Der) inefficien( II (%e ? %as (o "e conDer(e& (o eac% co#umn in (urn! w w T%e SQL parser %an&#es a## (%e fie#& references ") o"(aining (%e names of Da#i& co#umns from (%e &a(a &ic(ionar) an& su"s(i(u(es (%em on (%e comman& #ineC '%ic% is (ime consuming! w w

w w

39

Using S(L*)lus $ut*tr+ce


w w w Ef )oure using SQL?P#us )ou can (aJe a&Dan(age of (%e auto trace fea(ure (o %aDe Kueries e/p#aine& au(oma(ica##)! SQL?P#us 'i## e/ecu(e (%e Kuer) an& &isp#a) (%e e/ecu(ion p#an fo##o'ing (%e resu#(s! ,!g SQL2 SET )UTOT%)*E ON EXP+)IN
SQL2 SE+E*T animal2name #%OM a uatic2animal O%/E% 34 animal2name5
#"I,#L*"#,( ////////////////////////////// Batt& Bopper 3lipper

: =

6 rows selected. Execution Plan '''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 7 SE+E*T ST)TEMENT Optimi-er8*,OOSE 9*ost86 *ard8:7 31tes8:;7< 7 SO%T 9O%/E% 34< 9*ost86 *ard8:7 31tes8:;7< = : T)3+E )**ESS 9#U++< O# >)?U)TI*2)NIM)+@ 9*ost8: *ard8:7 31tes8:;7<
4

w w w SQL?P#us &oes e/ecu(e (%e Kuer)! Ef a Kuer) genera(es a #o( of EF1 an& consumes a #o( of 4P>C )ou 'on( 'an( (o JicJ i( off $us( (o see (%e e/ecu(ion p#an! w En (%a( case use fo##o'ing 3 S?+A SET )UTOT%)*E T%)*EON+4 EXP+)IN w )ou are (%roug% using au(o(raceC )ou can (urn (%e fea(ure off ") issuing (%e S(T #UTOTR#+( O33 comman&!

41

You might also like