程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> Oracle初級性能優化總結

Oracle初級性能優化總結

編輯:Oracle教程

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

1、避免使用select *

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

--- *  Table_Name1 
--- columnname1,columnname2,columnname3  Table_Name1

 

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

--- columnname  Table_Name1 t1,Table_Name2
--- t1.columnname  Table_Name1 t1,Table_Name2

 

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

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

--
---= outer.column_name)

 

4、用not exists 替代 not in
在子查詢中,not in子句將執行一個內部的排序和合並。無論在那種情況下,not in 都是低效的(因為它對子查詢中的表執行了一個全表遍歷)。為了避免使用 not in ,我們可以把它改寫成外連接(outer join)或 not exists。

--- columnname,columnname1  id not ( id  Table_Name2  name=)
--- columnname,columnname1  t1.id=<>
--- columnname,columnname1  not exists(   t2.id==)

 

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

--- columnname,columnname1  not exists(   t2.id==)
---= t2.name=

 

6、用exists替換distinct

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

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

--= t2.column_name;
---= outer.column_name)

 

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

 *  EMP  id>;
 *  EMP  id>=;

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

 

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

--- id,name,reg  Table_Name1  id= or reg=
--- id,name,reg  Table_Name1 t1  t1.id= id,name,reg  Table_Name2 t2  t2.reg=

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

 

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

--- id,name,reg  Table_Name1 t1  t1.id= id,name,reg  Table_Name2 t2  t2.id=
--- id,name,reg  Table_Name1 t1  t1.id= id,name,reg  Table_Name2 t2  t2.id=

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

 

10、避免在索引列上使用IS NULL和IS NOT NULL
對於單列索引,如果列包含空值,索引中將不存在此記錄。
對於復合索引,如果每個列都為空,索引中同樣不存在此記錄。如果至少有一個列不為空。則記錄存在於索引中。
因為空值不存在於索引列中,所以where子句中對索引列進行空值比較將使Oracle停用該索引。

--- id,name,reg  Table_Name1 t1  t1.id  not 
--- id,name,reg  Table_Name2 t2  t2.id>=

前提還是id列是索引列

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved