MySQL常用的sql語句優化總結
1、有索引但未被用到的情況
(1) Like的引數以萬用字元開頭時
儘量避免Like的引數以萬用字元開頭,否則資料庫引擎會放棄使用索引而進行全表掃描。
(2) where條件不符合最左字首原則時
例子已在最左字首匹配原則的內容中有舉例。
(3) 使用!= 或 <> 操作符時
儘量避免使用!= 或 <>操作符,否則資料庫引擎會放棄使用索引而進行全表掃描。使用>或<會比較高效。
(4) 索引列參與計算
應儘量避免在 where 子句中對欄位進行表示式操作,這將導致引擎放棄使用索引而進行全表掃描。
(5) 對欄位進行null值判斷
應儘量避免在where子句中對欄位進行null值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如: 低效:select * from t_credit_detail where Flistid is null ;
可以在Flistid上設定預設值0,確保表中Flistid列沒有null值,然後這樣查詢: 高效:select * from t_credit_detail where Flistid =0;
(6) 使用or來連線條件
應儘量避免在where子句中使用or來連線條件,否則將導致引擎放棄使用索引而進行全表掃描,如: 低效:select * from t_credit_detail where Flistid = '2000000608201108010831508721' or Flistid = '10000200001';
可以用下面這樣的查詢代替上面的 or 查詢: 高效:select from t_credit_detail where Flistid = '2000000608201108010831508721' union all select
2、避免select *
在解析的過程中,會將'*' 依次轉換成所有的列名,這個工作是通過查詢資料字典完成的,這意味著將耗費更多的時間。
所以,應該養成一個需要什麼就取什麼的好習慣。
3、order by 語句優化
任何在Order by語句的非索引項或者有計算表示式都將降低查詢速度。
方法:1.重寫order by語句以使用索引;
2.為所使用的列建立另外一個索引
3.絕對避免在order by子句中使用表示式。
4、GROUP BY語句優化
提高GROUP BY 語句的效率, 可以通過將不需要的記錄在GROUP BY 之前過濾掉
低效:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP by JOB
HAVING JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
高效:
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
GROUP by JOB
5、用 exists 代替 in
很多時候用 exists 代替 in 是一個好的選擇: select num from a where num in(select num from b) 用下面的語句替換: select num from a where exists(select 1 from b where num=a.num)
6、使用 varchar/nvarchar 代替 char/nchar
儘可能的使用 varchar/nvarchar 代替 char/nchar ,因為首先變長欄位儲存空間小,可以節省儲存空間,其次對於查詢來說,在一個相對較小的欄位內搜尋效率顯然要高些。
7、能用DISTINCT的就不用GROUP BY
SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID
可改為:
SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10
8、能用UNION ALL就不要用UNION
UNION ALL不執行SELECT DISTINCT函式,這樣就會減少很多不必要的資源。
9、在Join表的時候使用相當型別的例,並將其索引
如果應用程式有很多JOIN 查詢,你應該確認兩個表中Join的欄位是被建過索引的。這樣,MySQL內部會啟動為你優化Join的SQL語句的機制。
而且,這些被用來Join的欄位,應該是相同的型別的。例如:如果你要把 DECIMAL 欄位和一個 INT 欄位Join在一起,MySQL就無法使用它們的索引。對於那些STRING型別,還需要有相同的字符集才行。(兩個表的字符集有可能不一樣)