--選擇最有效率的表名順序:
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’io
--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()table