關於SQL語句優化的簡單整理:
關於SQL優化的日常整理:
(目前先整理這麼多,後期繼續完善)
-
新增索引(最有效的方式之一)
1). 什麼時候考慮新增索引?
場景:針對資料量特別大的時候(如上千萬條資料) ; 查詢頻率高(查詢次數較多的時候);
2). 針對什麼樣的欄位新增索引?
where條件後面跟著的欄位; 資料波動範圍大的欄位; 資料範圍波動小的, 可以考慮使用oracle的點陣圖索引; 如: 性別, 狀態.
3). 資料庫表的索引是否越多越好 ?
索引也不是越多越好; 太多反而影響 insert , update 的效率; 關於索引的使用應該注意: 1)資料量小的表不需要建立索引,因為資料量小的表即使建立索引也不會有太大的用處,還會增加額外的索引開銷 2)不經常使用的列不要建立索引,沒意義 3)經常更新比較頻繁的列不要建立索引,會影響insert , update 的效率
4). 索引的使用規則?
EXPLAIN 解釋select 的執行計劃 (mysql);
-
select 語句中 儘量不適用 select * from…, 使用具體的欄位代替 select name , age from …;
—> select * , * 代表所有的列, 不同的表, 列也不同, 需要解析列, 會查詢所有的欄位. 效率低. -
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; —> 先分組後過濾.
-
如果需要查詢多張表, 可以使用子查詢, 也可以使用多表查詢時, 理論上,儘量使用多表查詢 —> 因為效能高.
因為子查詢, 對資料操作兩次或多次, 而多表查詢則只操作一次, 所以效率高---------> 不考慮笛卡爾積的情況下.
但是,如果表中的資料太多, 多表產生的笛卡爾積太大, 會影響多表查詢的效率.
-
儘量不使用集合運算.
參與運算的集合越多, 執行效率越低. UNION(並集) , UNION ALL(全並集) , INTERCEPT(交集) , MINUS(差集)
-
儘量不適用in操作符.
ORACLE試圖將其轉換成多個表的連線,如果轉換不成功則先執行IN裡面的子查詢,再查詢外層的表記錄,如果轉換成功則直接採
用多個表的連線方式查詢。由此可見用IN的SQL至少多了一個轉換的過程
在業務密集的SQL當中儘量不採用IN操作符,用 EXISTS 方案代替。
-
強烈不建議使用 not in 操作符.
此操作是強列不推薦使用的,因為它不能應用表的索引 ; 可以使用not exists來替代.
-
IS NULL 或IS NOT NULL操作(判斷欄位是否為空)
判斷欄位是否為空一般是不會應用索引的,因為索引是不索引空值的 ;
用其它相同功能的操作運算代替,如:a is not null 改為 a>0 或a>’’等。不允許欄位為空,
-
LIKE的模糊查詢如果用的不好也會降低效能.
LIKE操作符可以應用萬用字元查詢,裡面的萬用字元組合可能達到幾乎是任意的查詢,但是如果用得不好則會產生效能上的問題,
如LIKE ‘%5400%’ 這種查詢不會引用索引,而LIKE '5400%'則會使用索引
-
避免使用耗費資源的操作,帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啟動SQL引擎 執行,耗費資源的排序(SORT)功能.
-
在WHERE 語句中,儘量避免對索引欄位進行計算操作
避免在索引欄位上使用not,<>,!= 避免在索引列上使用IS NULL和IS NOT NULL 避免在索引列上出現數據型別轉換 避免在索引欄位上使用函式 避免建立索引的列中使用空值
-
儘量使用預編譯的SQL;
因為預編譯的SQL語句, 傳送給資料庫時包含兩個部分 : 1). sql語句 ; 2).引數資訊;
sql語句編譯之後, 會將其快取在資料庫中, 下一次再次請求該語句時, 不會再執行編譯的過程.*