1. 程式人生 > >關於SQL語句優化的簡單整理:

關於SQL語句優化的簡單整理:

關於SQL優化的日常整理:
(目前先整理這麼多,後期繼續完善)

  1. 新增索引(最有效的方式之一)

    1). 什麼時候考慮新增索引?

     場景:針對資料量特別大的時候(如上千萬條資料) ; 查詢頻率高(查詢次數較多的時候);
    

    2). 針對什麼樣的欄位新增索引?

     where條件後面跟著的欄位; 資料波動範圍大的欄位;
     
     資料範圍波動小的, 可以考慮使用oracle的點陣圖索引; 如: 性別, 狀態.
    

    3). 資料庫表的索引是否越多越好 ?

     索引也不是越多越好; 太多反而影響 insert , update 的效率;
     
     關於索引的使用應該注意:
     	
     	1)資料量小的表不需要建立索引,因為資料量小的表即使建立索引也不會有太大的用處,還會增加額外的索引開銷
     	2)不經常使用的列不要建立索引,沒意義
     	3)經常更新比較頻繁的列不要建立索引,會影響insert , update 的效率
    

    4). 索引的使用規則?

     EXPLAIN 解釋select 的執行計劃 (mysql);
    
  2. select 語句中 儘量不適用 select * from…, 使用具體的欄位代替 select name , age from …;
    —> select * , * 代表所有的列, 不同的表, 列也不同, 需要解析列, 會查詢所有的欄位. 效率低.

  3. where 和 having, where子句中不能跟組函式. 當使用where 和 having 都可以使用時, 儘量使用where.

    1). select deptno, avg(sal) from emp where deptno = 10 group by deptno; —> 先過濾,後分組, 分組的物件資料少, 效率高.

    2). select deptno, avg(sal) from emp group by deptno having deptno = 10; —> 先分組後過濾.

  4. 如果需要查詢多張表, 可以使用子查詢, 也可以使用多表查詢時, 理論上,儘量使用多表查詢 —> 因為效能高.

    因為子查詢, 對資料操作兩次或多次, 而多表查詢則只操作一次, 所以效率高---------> 不考慮笛卡爾積的情況下.

    但是,如果表中的資料太多, 多表產生的笛卡爾積太大, 會影響多表查詢的效率.

  5. 儘量不使用集合運算.

    參與運算的集合越多, 執行效率越低. UNION(並集) , UNION ALL(全並集) , INTERCEPT(交集) , MINUS(差集)

  6. 儘量不適用in操作符.

    ORACLE試圖將其轉換成多個表的連線,如果轉換不成功則先執行IN裡面的子查詢,再查詢外層的表記錄,如果轉換成功則直接採

    用多個表的連線方式查詢。由此可見用IN的SQL至少多了一個轉換的過程

    在業務密集的SQL當中儘量不採用IN操作符,用 EXISTS 方案代替。

  7. 強烈不建議使用 not in 操作符.

    此操作是強列不推薦使用的,因為它不能應用表的索引 ; 可以使用not exists來替代.

  8. IS NULL 或IS NOT NULL操作(判斷欄位是否為空)

    判斷欄位是否為空一般是不會應用索引的,因為索引是不索引空值的 ;

    用其它相同功能的操作運算代替,如:a is not null 改為 a>0 或a>’’等。不允許欄位為空,

  9. LIKE的模糊查詢如果用的不好也會降低效能.

    LIKE操作符可以應用萬用字元查詢,裡面的萬用字元組合可能達到幾乎是任意的查詢,但是如果用得不好則會產生效能上的問題,

    如LIKE ‘%5400%’ 這種查詢不會引用索引,而LIKE '5400%'則會使用索引

  10. 避免使用耗費資源的操作,帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啟動SQL引擎 執行,耗費資源的排序(SORT)功能.

  11. 在WHERE 語句中,儘量避免對索引欄位進行計算操作

    	避免在索引欄位上使用not,<>,!=
    
    	避免在索引列上使用IS NULL和IS NOT NULL
    
    	避免在索引列上出現數據型別轉換
    
    	避免在索引欄位上使用函式
    
    	避免建立索引的列中使用空值
    
  12. 儘量使用預編譯的SQL;
    因為預編譯的SQL語句, 傳送給資料庫時包含兩個部分 : 1). sql語句 ; 2).引數資訊;
    sql語句編譯之後, 會將其快取在資料庫中, 下一次再次請求該語句時, 不會再執行編譯的過程.*