oracle – SQL最佳化

來源:互聯網
上載者:User

 最佳化規則:

1.CBO模式下,表從右至左查詢,右邊第一個為基礎資料表
選擇行數的少作為基礎資料表,
三個及三個以上的表,需要選擇交叉表(串連另外兩個表的表)作為基礎資料表,

2.資料量大的時候,使用exists 而非 in

3.where
自下而上的解析where子句,
過濾資料記錄的條件寫在where字句的
尾部,以便在過濾了資料之後在進行表串連處理(即 a.name='張三'的寫後面,再讓a表中欄位name為'張三'的資料去跟b表關聯)
select * from table_name a,ccc b
where a.column =b.column
and a.deptno in(20,30)

4.使用decode

語句塊使用短路徑,if( aa > 100) or (bb = 'cc'),
第一個對了,就不會走進第二個,
if( 1 = 2) and ( a in(1,2,3,4,5))
如果第一個就不滿足的話,也不會走進第二個
所以將開銷較低的放前面

5.避免隱式類型的轉換,把pls_integer複製給number時,會出現隱式轉換

 比較方法:

--查看對應行數語句塊的效能

1.還有一個是按F5鍵查看執行計畫

名詞解釋:

Cost:   操作消耗的成本(根據uses   disk   I/O,   CPU   usage,   memory   usage   等計算出來)
cardinality   操作訪問的資料行數
Bytes     操作訪問的資料集的大小。


2.一個是下面的方法
declare
  -- Local variables here
  v_run_number integer;
   p_contractid contract.contractid%type;
begin
  --啟動profiler
  dbms_profiler.start_profiler(run_number => v_run_number);
  --顯示當前跟蹤的運行行號
  dbms_output.put_line('run_number:' || v_run_number);
  --運行要跟蹤的PLSQL
  for aa in (select * from contract where rownum < 100) loop
   p_contractid:=aa.contractid;
  end loop;
  --停止profiler
  dbms_profiler.stop_profiler;
end;

 

 1.子查詢與串連查詢比較

大量資料子查詢時:

 大量資料連線查詢時:

 

--子查詢

View Code

 1 --有子查詢 2 select a.contractno       保單號碼, 3       (select  chnname from syscode where recordid =a.contractstatus)          狀態, 4        a.acceptdate       受理日期, 5        a.effectivedate    生效日期, 6        a.approvedate      承保日期, 7        a.policyreturndate 回單日期, 8        a.surrenderdate    退保日期, 9        b.checkyearmonth   對賬日期,10        max(b.policyyear)       年度,11        b.productname      險種名稱,12        b.premiumperiod    年期,13        (select abbrname from branch where branchid =b.bizcbranchid) 督導區,14        (select abbrname from branch where branchid=b.bizubranchid )   營業部,15        b.applicantname    投保人,16        b.insuredname      被保險人,17        a.AGENTNAME        代理人,18        b.modalprem        保費,19        b.valueprem        價值保費20   from contract a, premium b21  where  a.contractid = b.contractid22    and a.providerid in ('PRO0000000000006', 'PRO00000000000G6')23    and a.bizbranchid = 'BRA0000000000006'24    and a.channeltype = 'CHANNELTYPE_A'25     group by a.contractno,26           a.acceptdate,27           a.effectivedate,28           a.approvedate,29           a.policyreturndate,30           surrenderdate,31           checkyearmonth,32           productname,33           b.premiumperiod,34           b.applicantname,35           b.insuredname,36           a.AGENTNAME,37           modalprem,38           a.contractstatus,39           b.bizcbranchid,40           b.bizubranchid,41           b.valueprem 42    43    --select a.providerid,a.providername from provider a where providername like '%信泰%'44    --select * from syscode where recordid like '%CHANNEL%'

結果集都是14678條,花費的三次時間依次為 27.627 26.582 26.692

--串連查詢

View Code

 1 --全部是串連查詢 2 select a.contractno       保單號碼, 3       c.chnname         狀態, 4        a.acceptdate       受理日期, 5        a.effectivedate    生效日期, 6        a.approvedate      承保日期, 7        a.policyreturndate 回單日期, 8        a.surrenderdate    退保日期, 9        b.checkyearmonth   對賬日期,10        max(b.policyyear)       年度,11        b.productname      險種名稱,12        b.premiumperiod    年期,13        e.branchname 督導區,14        f.branchname  營業部,15        b.applicantname    投保人,16        b.insuredname      被保險人,17        a.AGENTNAME        代理人,18        b.modalprem        保費,19        b.valueprem        價值保費20   from contract a, premium b,syscode c,branch e,branch f21  where  a.contractid = b.contractid22  and c.recordid = a.contractstatus23  and b.bizcbranchid = e.branchid24  and b.cbranchid = f.branchid25   and a.channeltype = 'CHANNELTYPE_A'26    and a.providerid in ('PRO0000000000006', 'PRO00000000000G6')27    and a.bizbranchid = 'BRA0000000000006'28     group by a.contractno,29           a.acceptdate,30           a.effectivedate,31           a.approvedate,32           a.policyreturndate,33           surrenderdate,34           checkyearmonth,35           productname,36           b.premiumperiod,37           b.applicantname,38           b.insuredname,39           a.AGENTNAME,40           modalprem,41           c.chnname,42           e.branchname,43           f.branchname,44           b.valueprem 45    46    --select a.providerid,a.providername from provider a where providername like '%信泰%'

結果集都是14678條,花費的三次時間依次為 25.178 23.806 25.037

 

2.索引方面

  沒有建立索引之前

  建立索引之後

總結:效率提高接近100倍,那麼哪些欄位應該建立索引了?當你的一個不是很複雜的sql,例如上面的,花費的時間比較長,就應該從多方面調優,當其他方法無法調優,確實需要建立索引的時候,如,那個objectname的contract表花費了很長時間,看下你的where語句中有三個欄位用到了branchid,contractstatus,effectivedate,然後,機構ID(branchid)的值不多隻有幾百個,保單狀態(contractstatus)的值也不多,只有幾十個,但是生效時間(effectivedate)卻有千萬,一天365天,24小時,等等,所以慢就慢在這裡,加個索引 create index IDX_CONT_EFFECTIVEDATE on CONTRACT (EFFECTIVEDATE);索引這個用的好,效率提高,反之更慢,還會影響整個資料庫的效能。

索引介紹:http://www.cnblogs.com/o-andy-o/archive/2012/08/16/2641974.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.