oracle 一些經常使用的sql優化規則

1.高效使用groupby

提升GROUP BY語句的效率,能夠經過將不須要的記錄在GROUP BY以前過濾掉。html

低效:java

 SELECT JOB ,AVG(SAL)

    FROM EMP

  GROUP BY JOB

HAVING JOB = ‘PRESIDENT’

         OR JOB = ‘MANAGER’

高效:oracle

SELECT JOB,AVG(SAL)

   FROM EMP

WHERE JOB = ‘PRESIDENT’

        OR JOB = ‘MANAGER’

GROUP BY JOB

 

2.在存儲過程當中使用顯式遊標

使用隱式的遊標,將會執行兩次操做。第一次檢索記錄,第二次檢查TOO MANY ROWS 這個exception。而顯式遊標不執行第二次操做。

 

3.避免使用消耗資源的操做

帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啓動SQL引擎執行耗費資源的排序(SORT)功能。DISTINCT須要一次排序操做,而其餘的至少須要執行兩次排序。性能

 

4.用in代替or

SELECT….

  FROM LOCATION

WHERE LOC_ID = 10

       OR  LOC_ID = 20

       OR  LOC_ID = 30

高效:

SELECT…

  FROM LOCATION

WHERE LOC_IN IN (10,20,30)

 

5.靈活使用exists和in

當外表很大的時候,咱們一般使用exists代替in優化

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

可是關聯的條件比較少或者外表比較小的時候,用in效率高。spa

 

6.計算數量count效率高的寫法

Select count(*) from tablename; 
Select count(1) from tablename; 
Select max(rownum) from tablename;
 通常認爲,在沒有索引的狀況之下,第一種方式最快。 若是有索引列,使用索引列固然最快。

 

7.where子句中的鏈接順序

Oracle採用自下而上的順序解析WHERE子句。 根據這個原理,表之間的鏈接必須寫在其餘WHERE條件以前,那些能夠過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。
 
/*低效,執行時間156.3秒*/
SELECT … 
  FROM EMP E
WHERE  SAL > 50000
     AND  JOB = ‘MANAGER’
     AND  25 < (SELECT COUNT(*) FROM EMP
                         WHERE MGR = E.EMPNO)
 
 
/*高效,執行時間10.6秒*/
SELECT … 
  FROM EMP E
WHERE 25 < (SELECT COUNT(*) FROM EMP
                        WHERE MGR=E.EMPNO)
     AND SAL > 50000
     AND JOB = ‘MANAGER’

 

8.使用索引

全表掃描
  全表掃描就是順序地訪問表中每條記錄,ORACLE採用一次讀入多個數據塊(database block)的方式優化全表掃描。
經過ROWID訪問表
  ROWID包含了表中記錄的物理位置信息,ORACLE採用索引實現了數據和存放數據的物理位置(ROWID)之間的聯繫,
一般索引提供了快速訪問ROWID的方法,所以那些基於索引列的查詢就能夠獲得性能上的提升。

 

9.索引使用的一些注意點

1.常常進行鏈接查詢的列應該建立索引 2.若是有兩個或者以上的索引,其中有一個惟一性索引,而其餘是非惟一,這種狀況下oracle將使用惟一性索引而徹底忽略非惟一性索引 3.小表不要創建索引 4.對於基數大的列適合創建B樹索引,對於基數小的列適合簡歷位圖索引 5.列中有不少空值,但常常查詢該列上非空記錄時應該創建索引 6.使用create index時要將最常查詢的列放在最前面 7.LONG(可變長字符串數據,最長2G)和LONG RAW(可變長二進制數據,最長2G)列不能建立索引 8.限制表中索引的數量(建立索引耗費時間,而且隨數據量的增大而增大;索引會佔用物理空間;
當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,下降了數據的維護速度)

以上參考(https://www.cnblogs.com/zjfjava/p/7092503.html

 

 

還有須要注意一下沒法使用索引的查詢狀況:

1.不匹配的數據類型查詢條件:.net

好比咱們若是將一個日期類型的字段做爲索引時,卻用to_char(date)去做爲條件查詢,沒法使用索引。
或者索引字段是varchar2類型,咱們用to_number(字段)去查詢,它仍是會走全表掃描。

 

2.使用is not,!=或<>等表示不等於的操做符:(參考:https://blog.csdn.net/u010189382/article/details/37756269code

下面的查詢即便在cust_rating列有一個索引,查詢語句仍然執行一次全表掃描。 select cust_Id,cust_name from customers where cust_rating <> 'aa'; 把上面的語句改爲以下的查詢語句,這樣,在採用基於規則的優化器而不是基於代價的優化器(更智能)時,將會使用索引。 selectcust_Id,cust_name from customers where cust_rating < 'aa' or cust_rating > 'aa'; 特別注意:經過把不等於操做符改爲OR條件,就可使用索引,以免全表掃描。

 

3.將null做爲查詢條件htm

使用is null或者is not null做爲條件時沒法使用b樹索引,可是可使用位圖索引。
(關於2者的區別能夠看下個人另外一篇文章:http://www.javashuo.com/article/p-wcrmwnlj-cc.html)
相關文章
相關標籤/搜索