提升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
使用隱式的遊標,將會執行兩次操做。第一次檢索記錄,第二次檢查TOO MANY ROWS 這個exception。而顯式遊標不執行第二次操做。
帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啓動SQL引擎執行耗費資源的排序(SORT)功能。DISTINCT須要一次排序操做,而其餘的至少須要執行兩次排序。性能
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)
當外表很大的時候,咱們一般使用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
Select count(*) from tablename; Select count(1) from tablename; Select max(rownum) from tablename; 通常認爲,在沒有索引的狀況之下,第一種方式最快。 若是有索引列,使用索引列固然最快。
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’
全表掃描
全表掃描就是順序地訪問表中每條記錄,ORACLE採用一次讀入多個數據塊(database block)的方式優化全表掃描。
經過ROWID訪問表
ROWID包含了表中記錄的物理位置信息,ORACLE採用索引實現了數據和存放數據的物理位置(ROWID)之間的聯繫,
一般索引提供了快速訪問ROWID的方法,所以那些基於索引列的查詢就能夠獲得性能上的提升。
1.常常進行鏈接查詢的列應該建立索引 2.若是有兩個或者以上的索引,其中有一個惟一性索引,而其餘是非惟一,這種狀況下oracle將使用惟一性索引而徹底忽略非惟一性索引 3.小表不要創建索引 4.對於基數大的列適合創建B樹索引,對於基數小的列適合簡歷位圖索引 5.列中有不少空值,但常常查詢該列上非空記錄時應該創建索引 6.使用create index時要將最常查詢的列放在最前面 7.LONG(可變長字符串數據,最長2G)和LONG RAW(可變長二進制數據,最長2G)列不能建立索引 8.限制表中索引的數量(建立索引耗費時間,而且隨數據量的增大而增大;索引會佔用物理空間;
當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,下降了數據的維護速度)
1.不匹配的數據類型查詢條件:.net
好比咱們若是將一個日期類型的字段做爲索引時,卻用to_char(date)去做爲條件查詢,沒法使用索引。
或者索引字段是varchar2類型,咱們用to_number(字段)去查詢,它仍是會走全表掃描。
2.使用is not,!=或<>等表示不等於的操做符:(參考:https://blog.csdn.net/u010189382/article/details/37756269)code
下面的查詢即便在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)