1. 程式人生 > >oracle 優化相關

oracle 優化相關

--選擇最有效率的表名順序:
  Oracle的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最後的表(基礎表 driving table)將被最先處理,
  在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表。如果有3個以上的表連線查詢,
  那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表。
--WHERE子句中的連線順序: 
  Oracle採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連線必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。
 
--select 子句中避免使用*
  Oracle在解析的過程中, 會將‘*’依次轉換成所有的列名, 這個工作是通過查詢資料字典完成的, 這意味著將耗費更多的時間
 
--用Where子句替換HAVING子句
  HAVING 只會在檢索出所有記錄之後才對結果集進行過濾,而Where子句在檢索時過濾
  on、where、having這三個都可以加條件的子句中,on是最先執行,where次之,having最後
 
--用EXISTS替代IN、用NOT EXISTS替代NOT IN
  在許多基於基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接。在這種情況下,使用EXISTS(或NOT EXISTS)通常將提高查詢的效率。
  在子查詢中,NOT IN子句將執行一個內部的排序和合並。無論在哪種情況下,NOT IN都是最低效的 (因為它對子查詢中的表執行了一個全表遍歷)。
  為了避免使用NOT IN ,我們可以把它改寫成外連線(Outer Joins)或NOT EXISTS。
 
--SQL語句用大寫的;因為Oracle總是先解析SQL語句,把小寫的字母轉換成大寫的再執行。 

--在Java程式碼中儘量少用連線符“+”連線字串。
  一個'+'就會產生一個新物件
 
--用>=替代>:
  高效:SELECT * FROM EMP WHERE DEPTNO >=4 低效: SELECT * FROM EMP WHERE DEPTNO >3
  兩者的區別在於,前者DBMS將直接跳到第一個DEPT等於4的記錄而後者將首先定位到DEPTNO=3的記錄並且向前掃描到第一個DEPT大於3的記 錄。
 
--避免在索引列上使用NOT、IS NULL和IS NOT NULL:
  NOT會產生在和在索引列上使用函式相同的影響。當Oracle“遇到”NOT、IS NULL和IS NOT NULL,他就會停止使用索引轉而執行全表掃描。
 
--避免在索引列上使用計算。
  WHERE子句中,如果索引列是函式的一部分。優化器將不使用索引而使用全表掃描。
 
  避免對索引欄位進行計算操作
  避免在索引欄位上使用not,<>,!=
  避免在索引列上使用IS NULL和IS NOT NULL
  避免在索引列上出現數據型別轉換
  避免在索引欄位上使用函式
  避免建立索引的列中使用空值。

--用UNION替換OR (適用於索引列):
  通常情況下,用UNION替換WHERE子句中的OR將會起到較好的效果。對索引列使用OR將造成全表掃描。
  注意,以上規則只針對多個索引列有效。如果有 column沒有被索引,查詢效率可能會因為你沒有選擇OR而降低。

--總是使用索引的第一個列: 
  如果索引是建立在多個列上,只有在它的第一個列(leading column)被where子句引用時,優化器才會選擇使用該索引。
  這也是一條簡單而重要的規則,當僅引用索引的第二個列時,優化器使用了全表掃描而忽略 了索引。 

--‘||'是字元連線函式、‘+'是數學函式。就象其他函式那樣, 停用了索引。 

--相同的索引列不能互相比較,這將會啟用全表掃描。 

--模糊查詢like
 %yue%,由於yue前面用到了“%”,因此該查詢必然走全表掃描,除非必要,否則不要在關鍵詞前加%。                               


--不要以字元格式宣告數字,要以數字格式宣告字元值。(日期同樣)否則會使索引無效,產生全表掃描
 使用    :SELECT emp.ename, emp.job FROM emp WHERE emp.empno = 7369;
 不要使用:SELECT emp.ename, emp.job FROM emp WHERE emp.empno = ‘7369’

--LEFT JOIN 和 inner join
 是否真的需要left join,否則選用inner join 來減少不必要的資料返回。
 連表查詢n*m,那麼減少基礎表的記錄數目可以有效的提高效率(把查詢條件放入到基礎表先進行過濾,然後在進行連線)
 select top 500 * from
(select  * from  [dbo].[table1] where (ss between @a1 and @a2)) a
 LEFT JOIN  dbo.[table2] ON a.m = dbo.[table2].n
 
--應避免在where子句中使用or來連線條件,否則引擎將放棄使用索引而進行全表掃描
--應儘量避免在 where 子句中對欄位進行表示式操作,這將導致引擎放棄使用索引而進行全表掃描。如:trim()