Oracle 創建索引及SQL優化

數據庫索引:數據庫

索引有單列索引 複合索引之說函數

如何某表的某個字段有主鍵約束和惟一性約束,則Oracle 則會自動在相應的約束列上建議惟一索引。數據庫索引主要進行提升訪問速度。優化

建設原則:排序

 一、索引應該常常建在Where 子句常常用到的列上。若是某個大表常用某個字段進行查詢,而且檢索行數小於總錶行數的5%。則應該考慮。索引

 二、對於兩錶鏈接的字段,應該創建索引。若是常常在某表的一個字段進行Order By 則也通過進行索引。io

 三、不該該在小表上建設索引。效率

優缺點:  一、索引主要進行提升數據的查詢速度。 當進行DML時,會更新索引。所以索引越多,則DML越慢,其須要維護索引。 所以在建立索引及DML須要權衡。基礎

建立索引:  單一索引:Create Index <Index-Name> On <Table_Name>(Column_Name);sed

 複合索引: Create Index i_deptno_job on emp(deptno,job); —>在emp表的deptno、job列創建索引。select

  select * from emp where deptno=66 and job='sals' ->走索引。

  select * from emp where deptno=66 OR job='sals' ->將進行全表掃描。不走索引

  select * from emp where deptno=66 ->走索引。

  select * from emp where job='sals' ->進行全表掃描、不走索引。

  若是在where 子句中有OR 操做符或單獨引用Job 列(索引列的後面列) 則將不會走索引,將會進行全表掃描。

Sql 優化:

當Oracle數據庫拿到SQL語句時,其會根據查詢優化器分析該語句,並根據分析結果生成查詢執行計劃。 也就是說,數據庫是執行的查詢計劃,而不是Sql語句。 查詢優化器有rule-based-optimizer(基於規則的查詢優化器) 和Cost-Based-optimizer(基於成本的查詢優化器)。 其中基於規則的查詢優化器在10g版本中消失。 對於規則查詢,其最後查詢的是全表掃描。而CBO則會根據統計信息進行最後的選擇。

一、先執行From ->Where ->Group By->Order By

二、執行From 字句是從右往左進行執行。所以必須選擇記錄條數最少的表放在右邊。這是爲何呢?  

三、對於Where字句其執行順序是從後向前執行、所以能夠過濾最大數量記錄的條件必須寫在Where子句的末尾,而對於多表之間的鏈接,則寫在以前。 由於這樣進行鏈接時,能夠去掉大多不重複的項。  

  1. SELECT子句中避免使用()ORACLE在解析的過程當中, 會將’’ 依次轉換成全部的列名, 這個工做是經過查詢數據字典完成的, 這意味着將耗費更多的時間

五、索引失效的狀況:  ① Not Null/Null 若是某列創建索引,當進行Select * from emp where depto is not null/is null。 則會是索引失效。  ② 索引列上不要使用函數,SELECT Col FROM tbl WHERE substr(name ,1 ,3 ) = 'ABC' 或者SELECT Col FROM tbl WHERE name LIKE '%ABC%' 而SELECT Col FROM tbl WHERE name LIKE 'ABC%' 會使用索引。

 ③ 索引列上不能進行計算SELECT Col FROM tbl WHERE col / 10 > 10 則會使索引失效,應該改爲 SELECT Col FROM tbl WHERE col > 10 * 10

 ④ 索引列上不要使用NOT ( != 、 <> )如:SELECT Col FROM tbl WHERE col ! = 10 應該 改爲:SELECT Col FROM tbl WHERE col > 10 OR col < 10 。

六、用UNION替換OR(適用於索引列)   union:是將兩個查詢的結果集進行追加在一塊兒,它不會引發列的變化。 因爲是追加操做,須要兩個結果集的列數應該是相關的, 而且相應列的數據類型也應該至關的。union 返回兩個結果集,同時將兩個結果集重複的項進行消除。 若是不進行消除,用UNOIN ALL.

一般狀況下, 用UNION替換WHERE子句中的OR將會起到較好的效果. 對索引列使用OR將形成全表掃描. 注意, 以上規則只針對多個索引列有效. 若是有column沒有被索引, 查詢效率可能會由於你沒有選擇OR而下降. 在下面的例子中, LOC_ID 和REGION上都建有索引.

  高效:   SELECT LOC_ID , LOC_DESC , REGION   FROM LOCATION   WHERE LOC_ID = 10   UNION   SELECT LOC_ID , LOC_DESC , REGION   FROM LOCATION   WHERE REGION = 「MELBOURNE」

  低效:   SELECT LOC_ID , LOC_DESC , REGION   FROM LOCATION   WHERE LOC_ID = 10 OR REGION = 「MELBOURNE」   若是你堅持要用OR, 那就須要返回記錄最少的索引列寫在最前面.

  1. 用EXISTS替代IN、用NOT EXISTS替代NOT IN 在許多基於基礎表的查詢中, 爲了知足一個條件, 每每須要對另外一個表進行聯接. 在這種狀況下, 使用EXISTS(或NOT EXISTS)一般將提升查詢的效率. 在子查詢中, NOT IN子句將執行一個內部的排序和合並. 不管在哪一種狀況下, NOT IN都是最低效的(由於它對子查詢中的表執行了一個全表遍歷). 爲了不使用NOT IN, 咱們能夠把它改寫成外鏈接(Outer Joins)或NOT EXISTS.

例子:

高效: SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)

低效: SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)

相關文章
相關標籤/搜索