亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Oracle中優化SQL的原則(轉貼)

系統 2068 0

?


  1。已經檢驗的語句和已在共享池中的語句之間要完全一樣
  2。變量名稱盡量一致
  3。合理使用外聯接
  4。少用多層嵌套
  5。多用并發

  語句的優化步驟一般有:
  1。調整sga區,使得sga區的是用最優。
  2。sql語句本身的優化,工具有explain,sql trace等
  3。數據庫結構調整
  4。項目結構調整
  寫語句的經驗:
  1。對于大表的查詢使用索引
  2、少用in,exist等
  3、使用集合運算

  1.對于大表查詢中的列應盡量避免進行諸如
  To_char,to_date,to_number
  等轉換
  2.有索引的盡量用索引,有用到索引的條件寫在前面
  如有可能和有必要就建立一些索引
  3.盡量避免進行全表掃描,限制條件盡可能多,以便更快
  搜索到要查詢的數據

  如何讓你的 SQL 運行得更快

  人們在使用SQL時往往會陷入一個誤區,即太關注于所得的結果是否正確,而忽略了不同的實現方法之間可能存在的性能差異,這種性能差異在大型的或是復雜的數據庫環境中(如聯機事務處理OLTP或決策支持系統DSS)中表現得尤為明顯。筆者在工作實踐中發現,不良的SQL往往來自于不恰當的索引設計、不充份的連接條件和不可優化的where子句。在對它們進行適當的優化后,其運行速度有了明顯地提高!下面我將從這三個方面分別進行總結:
中國網管聯盟www、bitsCN、com


  為了更直觀地說明問題,所有實例中的SQL運行時間均經過測試,不超過1秒的均表示為(< 1秒)。

  測試環境--
  主機:HP LH II
  主頻:330MHZ
  內存:128兆
  操作系統:Operserver5.0.4
  數據庫:Sybase11.0.3

一、不合理的索引設計

  例:表record有620000行,試看在不同的索引下,下面幾個 SQL的運行情況:
  1.在date上建有一非個群集索引

  select count(*) from record where date >
  '19991201' and date < '19991214'and amount >
  2000 (25秒)
  select date,sum(amount) from record group by date
  (55秒)
  select count(*) from record where date >
  '19990901' and place in ('BJ','SH') (27秒)
  分析:
  date上有大量的重復值,在非群集索引下,數據在物理上隨機存放在數據頁上,在范圍查找時,必須執行一次表掃描才能找到這一范圍內的全部行。

  2.在date上的一個群集索引

  select count(*) from record where date >
  '19991201' and date < '19991214' and amount >
  2000 (14秒) 網管網bitsCN.com
  select date,sum(amount) from record group by date
  (28秒)
  select count(*) from record where date >
  '19990901' and place in ('BJ','SH')(14秒)
  分析:
  在群集索引下,數據在物理上按順序在數據頁上,重復值也排列在一起,因而在范圍查找時,可以先找到這個范圍的起末點,且只在這個范圍內掃描數據頁,避免了大范圍掃描,提高了查詢速度。

  3.在place,date,amount上的組合索引

  select count(*) from record where date >
  '19991201' and date < '19991214' and amount >
  2000 (26秒)
  select date,sum(amount) from record group by date
  (27秒)
  select count(*) from record where date >
  '19990901' and place in ('BJ, 'SH')(< 1秒)
  分析:
  這是一個不很合理的組合索引,因為它的前導列是place,第一和第二條SQL沒有引用place,因此也沒有利用上索引;第三個SQL使用了place,且引用的所有列都包含在組合索引中,形成了索引覆蓋,所以它的速度是非常快的。

  4.在date,place,amount上的組合索引

  select count(*) from record where date >
feedom.net

  '19991201' and date < '19991214' and amount >
  2000(< 1秒)
  select date,sum(amount) from record group by date
  (11秒)
  select count(*) from record where date >
  '19990901' and place in ('BJ','SH')(< 1秒)
  分析:
  這是一個合理的組合索引。它將date作為前導列,使每個SQL都可以利用索引,并且在第一和第三個SQL中形成了索引覆蓋,因而性能達到了最優。

  5.總結:

  缺省情況下建立的索引是非群集索引,但有時它并不是最佳的;合理的索引設計要建立在對各種查詢的分析和預測上。一般來說:

  ①.有大量重復值、且經常有范圍查詢

  (between, >,< ,>=,< =)和order by
  、group by發生的列,可考慮建立群集索引;
  ②.經常同時存取多列,且每列都含有重復值可考慮建立組合索引;

  ③.組合索引要盡量使關鍵查詢形成索引覆蓋,其前導列一定是使用最頻繁的列。

二、不充份的連接條件:

  例:表card有7896行,在card_no上有一個非聚集索引,表account有191122行,在 account_no上有一個非聚集索引,試看在不同的表連接條件下,兩個SQL的執行情況:
網管網bitsCN_com


  select sum(a.amount) from account a,
  card b where a.card_no = b.card_no(20秒)
  將SQL改為:
  select sum(a.amount) from account a,
  card b where a.card_no = b.card_no and a.
  account_no=b.account_no(< 1秒)

  分析:
  在第一個連接條件下,最佳查詢方案是將account作外層表,card作內層表,利用card上的索引,其I/O次數可由以下公式估算為:

  外層表account上的22541頁+(外層表account的191122行*內層表card上對應外層表第一行所要查找的3頁)=595907次I/O

  在第二個連接條件下,最佳查詢方案是將card作外層表,account作內層表,利用account上的索引,其I/O次數可由以下公式估算為:

  外層表card上的1944頁+(外層表card的7896行*內層表account上對應外層表每一行所要查找的4頁)= 33528次I/O

  可見,只有充份的連接條件,真正的最佳方案才會被執行。

  總結:

  1.多表操作在被實際執行前,查詢優化器會根據連接條件,列出幾組可能的連接方案并從中找出系統開銷最小的最佳方案。連接條件要充份考慮帶有索引的表、行數多的表;內外表的選擇可由公式:外層表中的匹配行數*內層表中每一次查找的次數確定,乘積最小為最佳方案。 網管聯盟www.bitsCN.com

  2.查看執行方案的方法-- 用set showplanon,打開showplan選項,就可以看到連接順序、使用何種索引的信息;想看更詳細的信息,需用sa角色執行dbcc(3604,310,302)。

三、不可優化的where子句

  1.例:下列SQL條件語句中的列都建有恰當的索引,但執行速度卻非常慢:

  select * from record where
  substring(card_no,1,4)='5378'(13秒)
  select * from record where
  amount/30< 1000(11秒)
  select * from record where
  convert(char(10),date,112)='19991201'(10秒)
  分析:
  where子句中對列的任何操作結果都是在SQL運行時逐列計算得到的,因此它不得不進行表搜索,而沒有使用該列上面的索引;如果這些結果在查詢編譯時就能得到,那么就可以被SQL優化器優化,使用索引,避免表搜索,因此將SQL重寫成下面這樣:

  select * from record where card_no like
  '5378%'(< 1秒)
  select * from record where amount
  < 1000*30(< 1秒)
  select * from record where date= '1999/12/01'
  (< 1秒)

  你會發現SQL明顯快起來!
feedom.net


  2.例:表stuff有200000行,id_no上有非群集索引,請看下面這個SQL:

  select count(*) from stuff where id_no in('0','1')
  (23秒)
  分析:
  where條件中的'in'在邏輯上相當于'or',所以語法分析器會將in ('0','1')轉化為id_no ='0' or id_no='1'來執行。我們期望它會根據每個or子句分別查找,再將結果相加,這樣可以利用id_no上的索引;但實際上(根據showplan),它卻采用了"OR策略",即先取出滿足每個or子句的行,存入臨時數據庫的工作表中,再建立唯一索引以去掉重復行,最后從這個臨時表中計算結果。因此,實際過程沒有利用id_no上索引,并且完成時間還要受tempdb數據庫性能的影響。

  實踐證明,表的行數越多,工作表的性能就越差,當stuff有620000行時,執行時間竟達到220秒!還不如將or子句分開:

  select count(*) from stuff where id_no='0'
  select count(*) from stuff where id_no='1'
  得到兩個結果,再作一次加法合算。因為每句都使用了索引,執行時間只有3秒,在620000行下,時間也只有4秒。或者,用更好的方法,寫一個簡單的存儲過程:
  create proc count_stuff as
  declare @a int 中國網管聯盟www.bitscn.com
  declare @b int
  declare @c int
  declare @d char(10)
  begin
  select @a=count(*) from stuff where id_no='0'
  select @b=count(*) from stuff where id_no='1'
  end
  select @c=@a+@b
  select @d=convert(char(10),@c)
  print @d

  直接算出結果,執行時間同上面一樣快!

總結:

  可見,所謂優化即where子句利用了索引,不可優化即發生了表掃描或額

Oracle中優化SQL的原則(轉貼)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 九九九精品视频免费 | 精品在线一区二区三区 | 精品香蕉一区二区三区 | 中文字幕在线观看2023 | 九九热在线视频观看这里只有精品 | 久久国产精品一区二区 | 在线播放国产视频 | 亚洲视频在线观看免费视频 | 四虎影视永久免费观看网址 | 欧美亚洲国产精品久久高清 | 国产精品一区二区手机看片 | 男人的天堂免费在线观看 | 成人97在线观看免费高清 | 五月月色开心婷婷久久合 | 成人影院wwwwwwwwwww | 九九99热久久国产 | 欧美成人免费在线视频 | 97影院理论片在线观看 | 色综合在 | 色哦色哦哦色天天综合 | 国产精品亚洲成在人线 | 99视频免费看 | 欧美69p| 伊人成影院九九 | 精品国产一区二区三区久久影院 | 伊人中文字幕 | xxxx免费观看| 欧美乱人免费视频观看 | 最新99国产成人精品视频免费 | 精品国产精品a | 日本天天色 | 国产99视频在线观看 | 亚洲图片综合区另类图片 | 欧美区视频 | 欧美综合色另类图片区 | 国产精品久久久久久久久夜色 | 2020亚洲欧美日韩在线观看 | 九九99香蕉在线视频美国毛片 | 欧美视频在线网站 | 国产精品所毛片视频 | 不卡高清av手机在线观看 |