欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Oracle

系統 1996 0

Oracle初級性能優化總結

?

前言

  關于對Oracle數據庫查詢性能優化的一個簡要的總結。 從來數據庫優化都是一項艱巨的任務。對于大數據量,訪問頻繁的系統,優化工作顯得尤為重要。由于Oracle系統的靈活性、復雜性、性能問題的原因多樣性以及Oralce數據庫的動態特性,優化成為Oracle數據庫管理中最困難的領域。作為一個對數據庫了解不多的程序猿,我也只能從最基本的開始著手,慢慢來學習掌握Oracle的基礎吧。

示例

1、避免使用select *

  當你想在select字句中列出所有的column時,使用“select *”是一個方便的方法。不幸的是,這是一個低效的方法。實際上,Oracle在解析的過程中,會將‘*’依次轉換成所有的列名,這個工作是通過查詢數據字典完成的,這意味著將耗費更多的時間。

          ---
          
            糟糕的查詢


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


          
          
            select
          
           columnname1,columnname2,columnname3 
          
            from
          
           Table_Name1
        

?

2、使用表的別名
當在SQL語句中連接多個表時,請使用表的別名并把別名前綴于每個column上。這樣一來,就可以減少解析的時間并減少那些由column歧義引起的語法錯誤。
column歧義指的是由于SQL中不同的表具有相同的column名,當SQL語句中出現這個column時,SQL解析器無法判斷這個column的歸屬。

          ---
          
            糟糕的查詢


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


          
          
            select
          
           t1.columnname 
          
            from
          
           Table_Name1 t1,Table_Name2
        

?

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

例子:從小賣部買東西(商品),假如有個庫存表Table1,買東西出庫表Table2.查找庫存中的商品,是否有被賣出的,有的話就輸出庫存信息。

          --
          
            糟糕的查詢

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子句將執行一個內部的排序和合并。無論在那種情況下,not in 都是低效的(因為它對子查詢中的表執行了一個全表遍歷)。為了避免使用 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
通常來說,采用表連接的方式比Exists更有效率。
但是很多情況下我們無法將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

當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在select字句中使用distinct。一般可以考慮用Exists替換。Exists使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結果。

例子:從小賣部買東西(商品),假如有個庫存表Table_Name1,買東西出庫表Table_Name2.查找庫存中的商品,是否有被賣出的,有的話就輸出庫存信息。

          --
          
            糟糕的查詢

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上有一個索引,則:

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

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

?

8、用UNION替換OR
通常情況下,用UNION替換where字句中的OR將會起到較好的效果。對索引列使用OR將造成全表掃描。注意,以上規則只針對多個索引列有效。查詢效率可能會因為沒有選擇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
          
          
            '
          
        

當然以上要基于id列和reg列都是索引列。

?

9、用UNION-ALL 替換UNION
當SQL語句需要UNION兩個查詢結果集合時,這兩個結果集合會以UNION-ALL的方式被合并,然后在輸出最終結果前進行排序,并將重復記錄過濾掉。
如果用UNION ALL替代UNION,這樣排序就不是必要了,效率會因此得到提高。
需要注意的是,UNION ALL將重復輸出兩個結果集合中相同記錄,因此還是要從業務需求 分析使用UNION ALL的可行性。

          ---
          
            糟糕的查詢,需要進行排序

 
          
          
            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
          
        

考慮的時候一定也要基于業務的需求進行取舍。

?

10、避免在索引列上使用IS NULL和IS NOT NULL
對于單列索引,如果列包含空值,索引中將不存在此記錄。
對于復合索引,如果每個列都為空,索引中同樣不存在此記錄。如果至少有一個列不為空。則記錄存在于索引中。
因為空值不存在于索引列中,所以where子句中對索引列進行空值比較將使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列是索引列

總結

?  本節暫時總結到這里,之后繼續進行總結,感覺還是很有用的,然后在日常的工作中加以實踐,應該對自己的能力有所改善。上面總結的都是常規的做法,當然具體優化還要根據具體的環境進行處理,處理方式復雜多變,但萬變不離其宗。如有錯誤,請及時通知加以更正,謝謝。

?
?
分類:? SQL

Oracle


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产成人在线影院 | 亚洲呦呦系列视频 | 在线色网站 | 久久草在线视频免费 | 九九精品视频在线观看九九 | 欧美国产中文字幕 | 欧美日韩国产一区二区三区播放 | 亚洲精品久久久久久久久久吃药 | 成人永久福利免费观看 | 午夜爱爱爱爱爽爽爽网站免费 | 色偷偷精品视频在线播放放 | av在线一区二区三区 | 欧美搞黄视频 | 日韩在线中文字幕 | 99久久人妻无码精品系列性欧美 | 亚洲精品亚洲人成人网 | 日韩精品欧美一区二区三区 | 国产91色在线 | 亚洲 | 亚洲已满18点击进入在线观看 | 亚洲精品免费观看 | 99精品视频在线这里只有 | 日韩手机在线观看 | 亚洲一区二区三区高清 | 成人免费网视频 | 91在线视频观看 | 91香蕉嫩草 | 免费特黄一级欧美大片在线看 | 国产 一区 | 免费一级做a爰片性视频 | 国产91色在线 | 亚洲 | 午夜在线小视频 | 日日爽天天操 | 天天草天天爱 | 亚洲人在线 | 日韩欧美一区二区三区视频 | 日韩有码一区 | 色小说香蕉 | 日韩精品高清在线 | 97国产精品视频人人做人人爱 | 日本一区二区不卡 | 一区二区三区四区不卡视频 |