webinar

Post on 31-Oct-2014

14 Views

Category:

Documents

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

Webinar discription

TRANSCRIPT

Making  Impac,ul  Performance  Changes  

Karen  Morton  Sr.  Technical  Consultant  

1  

An  Embarcadero  Oracle  Community  Webinar    

karenmorton.blogspot.com  

karen_morton  

karen.morton@enkitec.com  

3  

July  31  Diagnosing  SQL  Performance  Problems  

 August  29  

Making  SQL  Performance  SoluIons  “SIck”    

September  26  Making  Impac,ul  Performance  Changes  

Topics  

•  Common  ways  to  rewrite  SQL  to  make  it  perform  beNer  and  more  consistently  

•  How  and  when  to  index  – AddiIons  or  modificaIons  to  provide  best  soluIon  

•  About  SQL  Tuning  Advisor  – When  it  helps  – When  it  doesn't  

4  

5  

Rewriting

SQL

First  things  first  

(This  stuff  is  really  important)  

Review  the  statement.    

What  is  it            supposed                      to  do?  

 

Tune  the  quesIon,  not  the  query.                        –    Tom  Kyte  

 

Collect  data.    

Review  staIsIcs.    

indexes    and    

                 constraints.  

Check  

Execute  the  query.  

Evaluate  the  plan.  

(compare  esImates  to  actuals)  

Where  are  the    big  hiNers?  

Refactor  the  statement.  

(if  you  should)  

Modify  or  Add  indexes,  constraints,  staIsIcs.  

(if  you  should)  

T  T  D  (Test  To  DestrucIon)  

Iterate  unIl  target  met  or  no  

further  improvement  possible  

Things    To  Keep  In  Mind  

How  do  you  do  simple,    yet  effecIve,  tesIng?  

Name  your  SQL  SELECT /* kmtest */ … FROM tab …

/*+  gather_plan_staIsIcs  */  (staIsIcs_level  =  ALL)  

dbms_xplan.display_cursor  ('ALLSTATS  LAST')  

SELECT xplan.*!FROM !(!select max(sql_id) keep! (dense_rank last order by last_active_time) sql_id! , max(child_number) keep! (dense_rank last order by last_active_time) child_number! from v$sql! where upper(sql_text) like '%&1%'! and upper(sql_text) not like !

! !'%FROM V$SQL WHERE UPPER(SQL_TEXT) LIKE %'!) sqlinfo,!table(DBMS_XPLAN.DISPLAY_CURSOR!(sqlinfo.sql_id, sqlinfo.child_number, 'ALLSTATS LAST')) xplan ;!!!

-- +COST +BYTES +PEEKED_BINDS!

/*+  monitor  */  

dbms_sqltune.report_sql_monitor  (TEXT,  HTML,  XML,  ACTIVE)  

SELECT dbms_sqltune.report_sql_monitor!(!! !SQL_ID => '&sql_id', !! !SESSION_ID => '&session_id',!! !SESSION_SERIAL => '&session_serial',!! !TYPE => '&report_format'!

) !FROM dual ;!

Monitored  statements  can  be  found  in  V$SQL_MONITOR  

Know  thy  data.  (and  thy  schema)  

Visualize  (Visual  SQL  Tuning)  

output  from  Embarcadero  DB  OpImizer  

33  

How  do  you  know  when  rewriIng  SQL  is  the  

best  opIon?  

Look  for    "column-­‐less"  joined  tables.  

SELECT b.* FROM a, b WHERE a.col1 = b.col1 AND b.col2 = <condition>

SELECT b.* FROM b WHERE b.col2 = <condition> AND EXISTS (SELECT null FROM a WHERE a.col1 = b.col1)

This  

Becomes  

Look  for    improper  outer  joins.  

AND tab1.col1 = tab2.col1 (+) AND tab2.col2 = <condition>

AND tab1.col1 = tab2.col1 AND tab2.col2 = <condition>

This  

Becomes  

Because  the  condiIon  would  be  null  for  the  outer  joined  row,    so  the  predicate  could  never  be  true.  

Look  for    repeated  use  of  same  tables  and  predicates.  

SELECT rite.event_name, count(*) FROM riffs.rf_order ro, riffs.rf_order_item roi, riffs.rf_item_transaction rit,

riffs.rf_item_transaction_event rite WHERE ro.is_test = '0' AND ro.order_id = roi.order_id AND roi.order_item_id = rit.order_item_id AND roi.order_id = rit.order_id AND rit.transaction_id = rite.transaction_id AND (rite.event_name >'AUTHORIZED' OR rite.event_name <'AUTHORIZED') GROUP BY rite.event_name UNION ALL SELECT 'TRANSACTION_INITIATED', count(*) FROM (SELECT count(*) FROM riffs.rf_order ro, riffs.rf_order_item roi,

riffs.rf_item_transaction rit, riffs.rf_item_transaction_event rite

WHERE ro.is_test = '0' AND ro.order_id = roi.order_id AND roi.order_item_id = rit.order_item_id AND roi.order_id = rit.order_id AND rit.transaction_id = rite.transaction_id AND rite.event_name = 'AUTHORIZED' GROUP BY substr(rit.TRANSACTION_ID,1,INSTR(rit.TRANSACTION_ID,'_')-1))

Look  for    simple  predicates  ORed  with  other  

predicates  in  ranges.  

AND col1 > <condition> OR col2 > <condition>

AND col1 > <condition> UNION / UNION ALL AND col2 > <condition>

This  

Becomes  

Because  a  row  could  not  be  rejected  when  one  predicate  is  false  without  checking  the  other  predicates.  

Look  for  DISTINCT/UNION  

to  remove  duplicates.  

Consider  using  IN  or  EXISTS  instead.  

Check  viability  of  indexes.  

Do  indexes  provide  proper  coverage?  

44  

How and When

to Index

45  

For  many  years,  inadequate  indexing  has  been  the  most    common  cause  of  performance  disappointments.    

–    Tapio  Lahdenmäki    

Indexing  Problems  

•  Indexes  that  do  not  have  sufficient  columns  to  support  all  predicates  

•  Not  enough  indexes  present  – Numerous  single-­‐column  but  few  mulI-­‐column  

•  Indexes  with  the  right  columns  but  in  the  wrong  order  

46  

47  

How  many  is  "too"  many?  

48  

Heavy  DML?  Large,  bulk  loads?  

or  Mostly  query?  

49  

Indexes  support  query  performance  

50  

SELECT !cust_id, cust_first_name!FROM! ! !customers!WHERE ! !cust_last_name = 'Ruddy'!AND! ! !cust_city = 'Ede'!ORDER BY cust_first_name ;!

Index  present  on  CUST_LAST_NAME,  CUST_FIRST_NAME  #  rows  in  table  =  55,500  

Inadequate  Index  

51  

Note  the  number  of  rows  that  are  thrown  away  in  step  1  (79).  

52  

Index  on  CUST_LAST_NAME,  CUST_CITY  No  throwaway  

Index  on  CUST_CITY,  CUST_LAST_NAME,  CUST_FIRST_NAME,  CUST_ID  No  throwaway,  no  sort  

Index  Strategies  

All  columns  from  equality  predicates    Add  columns  used  in  ORDER  BY    Add  all  remaining  columns  from  column  list  

53  

A  3  star  index  is  owen  called  a  "fat"  index.  Range  predicates  are  typically  placed  awer  1  and  2  star  columns.  

54  

The  key  to  determining  an  ideal  index      

The  index  should  provide  adequate  enough  screening  to  minimize  table  accesses.  

   

55  

SQL Tuning

Advisor

What  STA  Can  Recommend  

•  CollecIon  of  staIsIcs  – Objects  with  stale  or  missing  staIsIcs  are  idenIfied  and  appropriate  recommendaIons  are  made  to  remedy  the  problem  

•  CreaIon  of  new  indexes  –  Indexes  that  can  "significantly"  enhance  performance  

56  

What  STA  Can  Recommend  

•  Restructuring  of  the  SQL  statement  •  CreaIon  of  a  SQL  profile  – Remedy  execuIon  plan  inefficiencies  with  a  SQL  profile  

57  

Great  for  poinIng    out  the  "obvious".  

Finds  the  low-­‐hanging  fruit.  

59  

Finding:  An  expensive  cartesian  product  operaIon  was  found  at  line  ID  2  of  the  execuIon  plan.    RecommendaIons:  Consider  removing  the  disconnected  table  or  view  from  this  statement  or  add  a  join  condiIon  which  refers  to  it.    RaIonale:  A  cartesian  product  should  be  avoided  whenever  possible  because  it  is  an  expensive  operaIon  and  might  produce  a  large  amount  of  data.  

SQL  Restructuring  Example  1  

60  

Finding:  The  opImizer  could  not  unnest  the  subquery  at  line  ID  1  of  the  execuIon  plan.      RecommendaIons:  Consider  replacing  "NOT  IN"  with  "NOT  EXISTS"  or  ensure  that  columns  used  on  both  sides  of  the  "NOT  IN"  operator  are  declared  "NOT  NULL"  by  adding  either  "NOT  NULL"  constraints  or  "IS  NOT  NULL"  predicates.      

SQL  Restructuring  Example  2  

61  

RaIonale:  A  "FILTER"  operaIon  can  be  very  expensive  because  it  evaluates  the  subquery  for  each  row  in  the  parent  query.  The  subquery,  when  unnested  can  drasIcally  improve  the  execuIon  Ime  because  the  "FILTER"  operaIon  is  converted  into  a  join.  Be  aware  that  "NOT  IN"  and  "NOT  EXISTS"  might  produce  different  results  for  "NULL"  values.  

SQL  Restructuring  Example  2  

SQL  Profiles  use  OPT_ESTIMATE  

hints.  

"Fudge  factors"  

Not  a  subsItute  for  human  intelligence.    

Monkey  vs.  Astronaut  

Recap  

•  Look  for  common  anI-­‐paNerns  in  SQL  •  Gather  enough  diagnosIc  data  to  know  where  the  problem  originates  

•  Learn  what  the  opImizer  expects  (and  give  it  what  it  wants!)  

•  Think  about  your  indexing  strategy  •  Design  indexes  for  opImal  coverage  •  Use  STA  as  a  pointer  to  problems,  not  necessarily  as  the  soluIon  

 64  

Q  &  A  

65  

Thank  you!  

top related