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

Oracle

系統(tǒng) 1927 0

Oracle初級(jí)性能優(yōu)化總結(jié)

?

前言

  關(guān)于對(duì)Oracle數(shù)據(jù)庫(kù)查詢性能優(yōu)化的一個(gè)簡(jiǎn)要的總結(jié)。 從來(lái)數(shù)據(jù)庫(kù)優(yōu)化都是一項(xiàng)艱巨的任務(wù)。對(duì)于大數(shù)據(jù)量,訪問(wèn)頻繁的系統(tǒng),優(yōu)化工作顯得尤為重要。由于Oracle系統(tǒng)的靈活性、復(fù)雜性、性能問(wèn)題的原因多樣性以及Oralce數(shù)據(jù)庫(kù)的動(dòng)態(tài)特性,優(yōu)化成為Oracle數(shù)據(jù)庫(kù)管理中最困難的領(lǐng)域。作為一個(gè)對(duì)數(shù)據(jù)庫(kù)了解不多的程序猿,我也只能從最基本的開(kāi)始著手,慢慢來(lái)學(xué)習(xí)掌握Oracle的基礎(chǔ)吧。

示例

1、避免使用select *

  當(dāng)你想在select字句中列出所有的column時(shí),使用“select *”是一個(gè)方便的方法。不幸的是,這是一個(gè)低效的方法。實(shí)際上,Oracle在解析的過(guò)程中,會(huì)將‘*’依次轉(zhuǎn)換成所有的列名,這個(gè)工作是通過(guò)查詢數(shù)據(jù)字典完成的,這意味著將耗費(fèi)更多的時(shí)間。

          ---
          
            糟糕的查詢


          
          
            select
          
           * 
          
            from
          
           Table_Name1 
        
          ---
          
            較好的查詢


          
          
            select
          
           columnname1,columnname2,columnname3 
          
            from
          
           Table_Name1
        

?

2、使用表的別名
當(dāng)在SQL語(yǔ)句中連接多個(gè)表時(shí),請(qǐng)使用表的別名并把別名前綴于每個(gè)column上。這樣一來(lái),就可以減少解析的時(shí)間并減少那些由column歧義引起的語(yǔ)法錯(cuò)誤。
column歧義指的是由于SQL中不同的表具有相同的column名,當(dāng)SQL語(yǔ)句中出現(xiàn)這個(gè)column時(shí),SQL解析器無(wú)法判斷這個(gè)column的歸屬。

          ---
          
            糟糕的查詢


          
          
            select
          
           columnname 
          
            from
          
           Table_Name1 t1,Table_Name2
        
          ---
          
            較好的查詢


          
          
            select
          
           t1.columnname 
          
            from
          
           Table_Name1 t1,Table_Name2
        

?

3、用Exists 替代 in
在許多基于基礎(chǔ)表的查詢中,為了滿足一個(gè)條件,往往需要對(duì)另一個(gè)表進(jìn)行聯(lián)接。在這種情況下,使用exists(或not exists)通常將提高查詢的效率。

例子:從小賣部買東西(商品),假如有個(gè)庫(kù)存表Table1,買東西出庫(kù)表Table2.查找?guī)齑嬷械纳唐罚欠裼斜毁u出的,有的話就輸出庫(kù)存信息。

          --
          
            糟糕的查詢

SELECT column_name

FROM table_name1

WHERE column_name IN

( SELECT column_name

  FROM table_name2)
          
        
          ---
          
            較好的查詢

SELECT column_name

FROM table_name1 outer

WHERE EXISTS

  (SELECT 
          
          
            1
          
          
            

  FROM table_name2 inner

  WHERE inner.column_name 
          
          = outer.column_name)
        

?

4、用not exists 替代 not in
在子查詢中,not in子句將執(zhí)行一個(gè)內(nèi)部的排序和合并。無(wú)論在那種情況下,not in 都是低效的(因?yàn)樗鼘?duì)子查詢中的表執(zhí)行了一個(gè)全表遍歷)。為了避免使用 not in ,我們可以把它改寫成外連接(outer join)或 not exists。

          ---
          
            糟糕的查詢


          
          
            select
          
           columnname,columnname1 
          
            from
          
          
             Table_Name1 


          
          
            where
          
           id not 
          
            in
          
          (
          
            select
          
           id 
          
            from
          
           Table_Name2 
          
            where
          
           name=
          
            '
          
          
            A
          
          
            '
          
          )
        
          ---
          
            較好的查詢


          
          
            select
          
           columnname,columnname1 
          
            from
          
          
             Table_Name1 t1,Table_Name2 t2 


          
          
            where
          
           t1.id=
          
            t2.id

and t2.name
          
          <>
          
            '
          
          
            A
          
          
            '
          
        
          ---
          
            更好的查詢


          
          
            select
          
           columnname,columnname1 
          
            from
          
          
             Table_Name1 t1


          
          
            where
          
           not exists(
          
            select
          
          
            1
          
          
            from
          
          
             Table_Name2 t2


          
          
            where
          
           t2.id=
          
            t1.id

and t2.name
          
          =
          
            '
          
          
            A
          
          
            '
          
          )
        

?

5、用表連接替換Exists
通常來(lái)說(shuō),采用表連接的方式比Exists更有效率。
但是很多情況下我們無(wú)法將Exists改編為連接。

          ---
          
            糟糕的查詢


          
          
            select
          
           columnname,columnname1 
          
            from
          
          
             Table_Name1 t1


          
          
            where
          
           not exists(
          
            select
          
          
            1
          
          
            from
          
          
             Table_Name2 t2


          
          
            where
          
           t2.id=
          
            t1.id

and t2.name
          
          =
          
            '
          
          
            A
          
          
            '
          
          )
        
          ---
          
            較好的查詢


          
          
            select
          
          
             columnname,columnname1 


          
          
            from
          
          
             Table_Name1 t1

join Table_Name2 t2 on t1.id
          
          =
          
            t2.id


          
          
            where
          
           t2.name=
          
            '
          
          
            A
          
          
            '
          
        

?

6、用exists替換distinct

當(dāng)提交一個(gè)包含一對(duì)多表信息(比如部門表和雇員表)的查詢時(shí),避免在select字句中使用distinct。一般可以考慮用Exists替換。Exists使查詢更為迅速,因?yàn)镽DBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結(jié)果。

例子:從小賣部買東西(商品),假如有個(gè)庫(kù)存表Table_Name1,買東西出庫(kù)表Table_Name2.查找?guī)齑嬷械纳唐罚欠裼斜毁u出的,有的話就輸出庫(kù)存信息。

          --
          
            糟糕的查詢

SELECT DISTINCT t1.column_name

FROM table_name1 t1, table_name2 t2

WHERE t1.column_name 
          
          = t2.column_name;
        
          ---
          
            較好的查詢

SELECT column_name

FROM table_name1 outer

WHERE EXISTS

  (SELECT 
          
          
            1
          
          
            

  FROM table_name2 inner

  WHERE inner.column_name 
          
          = outer.column_name)
        

?

7、用>=替換>
如果id上有一個(gè)索引,則:

          
            ///
          
          
            糟糕的查詢
          
          
            select
          
           * 
          
            from
          
           EMP 
          
            where
          
           id>
          
            3
          
          ;
        
          
            //
          
          
            較好的查詢
          
          
            select
          
           * 
          
            from
          
           EMP 
          
            where
          
           id>=
          
            4
          
          ;
        

兩者的區(qū)別在于,后者將直接跳轉(zhuǎn)到第一個(gè)id等于4的記錄而前者將首先定位到id=3的記錄并且向前掃描到第一個(gè)id大于3的記錄。

?

8、用UNION替換OR
通常情況下,用UNION替換where字句中的OR將會(huì)起到較好的效果。對(duì)索引列使用OR將造成全表掃描。注意,以上規(guī)則只針對(duì)多個(gè)索引列有效。查詢效率可能會(huì)因?yàn)闆](méi)有選擇OR而降低。

          ---
          
            糟糕的查詢


          
          
            select
          
           id,name,reg 
          
            where
          
           Table_Name1 
          
            where
          
           id=
          
            10
          
           or reg=
          
            '
          
          
            A
          
          
            '
          
        
          ---
          
            較好的查詢

 
          
          
            select
          
           id,name,reg 
          
            from
          
           Table_Name1 t1 
          
            where
          
           t1.id=
          
            10
          
          
            

 union

 
          
          
            select
          
           id,name,reg 
          
            from
          
           Table_Name2 t2 
          
            where
          
           t2.reg=
          
            '
          
          
            A
          
          
            '
          
        

當(dāng)然以上要基于id列和reg列都是索引列。

?

9、用UNION-ALL 替換UNION
當(dāng)SQL語(yǔ)句需要UNION兩個(gè)查詢結(jié)果集合時(shí),這兩個(gè)結(jié)果集合會(huì)以UNION-ALL的方式被合并,然后在輸出最終結(jié)果前進(jìn)行排序,并將重復(fù)記錄過(guò)濾掉。
如果用UNION ALL替代UNION,這樣排序就不是必要了,效率會(huì)因此得到提高。
需要注意的是,UNION ALL將重復(fù)輸出兩個(gè)結(jié)果集合中相同記錄,因此還是要從業(yè)務(wù)需求 分析使用UNION ALL的可行性。

          ---
          
            糟糕的查詢,需要進(jìn)行排序

 
          
          
            select
          
           id,name,reg 
          
            from
          
           Table_Name1 t1 
          
            where
          
           t1.id=
          
            10
          
          
            

 union

 
          
          
            select
          
           id,name,reg 
          
            from
          
           Table_Name2 t2 
          
            where
          
           t2.id=
          
            10
          
        
          ---
          
            較好的查詢,不需要排序

 
          
          
            select
          
           id,name,reg 
          
            from
          
           Table_Name1 t1 
          
            where
          
           t1.id=
          
            10
          
          
            

 union  all

 
          
          
            select
          
           id,name,reg 
          
            from
          
           Table_Name2 t2 
          
            where
          
           t2.id=
          
            10
          
        

考慮的時(shí)候一定也要基于業(yè)務(wù)的需求進(jìn)行取舍。

?

10、避免在索引列上使用IS NULL和IS NOT NULL
對(duì)于單列索引,如果列包含空值,索引中將不存在此記錄。
對(duì)于復(fù)合索引,如果每個(gè)列都為空,索引中同樣不存在此記錄。如果至少有一個(gè)列不為空。則記錄存在于索引中。
因?yàn)榭罩挡淮嬖谟谒饕兄校詗here子句中對(duì)索引列進(jìn)行空值比較將使Oracle停用該索引。

          ---
          
            糟糕的查詢

 
          
          
            select
          
           id,name,reg 
          
            from
          
           Table_Name1 t1 
          
            where
          
           t1.id 
          
            is
          
           not 
          
            null
          
        
          ---
          
            較好的查詢


          
          
            select
          
           id,name,reg 
          
            from
          
           Table_Name2 t2 
          
            where
          
           t2.id>=
          
            10
          
        

前提還是id列是索引列

總結(jié)

?  本節(jié)暫時(shí)總結(jié)到這里,之后繼續(xù)進(jìn)行總結(jié),感覺(jué)還是很有用的,然后在日常的工作中加以實(shí)踐,應(yīng)該對(duì)自己的能力有所改善。上面總結(jié)的都是常規(guī)的做法,當(dāng)然具體優(yōu)化還要根據(jù)具體的環(huán)境進(jìn)行處理,處理方式復(fù)雜多變,但萬(wàn)變不離其宗。如有錯(cuò)誤,請(qǐng)及時(shí)通知加以更正,謝謝。

?
?
分類:? SQL

Oracle


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 欧美性理论片在线观看片免费 | 在线观看国产精品入口 | 羞羞网站视频 | 国内精品久久久久影院网站 | 免费一级a毛片在线播 | 成人短视频在线观看 | 免费看一毛一级毛片视频 | 俄罗斯一级毛片免费播放 | 免费看国产精品麻豆 | 九九99香蕉在线视频免费 | 欧美成人性videos | 国产乱码| 欧美天天爽| 夜夜嗨影院 | 色 综合 欧美 亚洲 国产 | 久久久久久久久久免费视频 | 久久精选视频 | 日日操天天 | 大学生一一级毛片在线播放 | 日日操影院 | 欧美成人在线视频 | 99久久国产亚洲综合精品 | 色综合夜夜嗨亚洲一二区 | 欧美中文字幕在线播放 | 羞羞的视频网站 | 夜夜爽日日澡人人添 | 亚洲视频在线免费观看 | 国产粉嫩白浆在线观看 | 手机看片国产 | 亚洲国产精品综合久久 | 国产亚洲第一伦理第一区 | 日本一级特黄毛片免费视频9 | 奇米影视狠狠干 | 不卡在线播放 | 伊人365影院| 国产尤物视频在线 | 免费视频一区二区三区四区 | 97成人免费视频 | 99欧美| 久久a视频| 色综合久久久久久久久久久 |