以下的文章主要介紹的是MySQL數據庫優化的實際操作以及相關推薦,前面我們也講過一些相關的優化操作策略,我們今天就一起來看看MySQL數據庫優化中Group BY 語句、 Order By語句 等。
優化GROUP BY語句
默認情況下,MySQL對所有GROUP BY col1,col2...的字段進行排序。這與在查詢中指定ORDER BY col1,col2...類似。因此,如果顯式包括一個包含相同的列的ORDER BY子句,則對MySQL的實際執行性能沒有什麼影響。 如果查詢包括GROUP BY 但用戶想要避免排序結果的消耗,則可以指定ORDER By NULL禁止排序,例如:
引用
- explain select id, sum(moneys) from sales2 group by id \G
- explain select id, sum(moneys) from sales2 group by id order by null \G
你可以通過比較發現第一條語句會比第二句在Extra:裡面多了Using filesort.而恰恰filesort是最耗時的。
MySQL數據庫優化ORDER BY語句
在某些情況中,MySQL可以使用一個索引來滿足ORDER BY子句,而不需要額外的排序。WHERE 條件和 ORDER BY使用相同的索引,並且ORDER BY的順序和索引順序相同,並且ORDER BY的字段都是升序或者都是降序。
例如:
引用
- SELECT * FROM t1 ORDER BY key_part1,key_part2,....:
- SELECT * FROM t1 WHERE key_part1 = 1 ORDER BY key_part1 DESC,key_part2 DESC;
- SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC;
但是以下的情況不使用索引:
引用
- SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
ORDER by的字段混合ASC 和 DESC
- SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
用於查詢行的關鍵字與ORDER BY 中所使用的不相同
- SELECT * FROM t1 ORDER BY key1, key2;
對不同的關鍵字使用ORDER BY
MySQL數據庫優化嵌套查詢
MySQL4.1開始支持SQL的子查詢。這個技術可以使用SELECT語句來創建一個單列的查詢結果,然後把這個查詢結果作為過濾條件用在另一個查詢中,使用子查詢可以一次性地完成多邏輯上需要多個步驟才能完成的SQL操作,同時也可以避免事務或者表鎖死,並且些起來也很容易。但是,有些情況下,子查詢可以被更有效的連接(JOIN)替代。
例如:
引用
- explain select * from sales2 where company_id not in(select id from company2) \G
- explain select * from sales2 left join comany2 on sales2.company_id =
company2.id where sales2.company_id is null \G;
第一句看起來比第二句更簡潔,但是第二句比第一就更快。因為使用JOIN來完成這個查詢,速度比較快,尤其如果對compay2表中的id建立了索引的話,那麼性能將會更好。那為什麼在這種情況下使用JOIN會更有效率呢。因為MySQL不需要在內存中創建臨時表來完成這個邏輯上需要兩個步驟的查詢工作。
優化OR條件
對於含有OR的查詢子句,如果要利用索引,則OR之間的每個條件列都必須用到索引;如果沒有索引,則考慮增加索引。
使用SQL提示
SQL 提示(SQL HINT)是MySQL數據庫優化數據庫的一個重要手段,簡單來說就是在SQL語句中加入一些人為的提示來達到優化的操作的目的。
例如:
引用
- SELECT SQL_BUFFER_RESULTS * FROM ...
這個語句將強制MySQL生成一個臨時結果集。只要臨時結果集生成後,所有表上的鎖定均被釋放。這能在遇到表鎖定問題時或者要花很長時間將結果傳給客戶端時所幫助,因為可以盡快釋放鎖資源,
下面是一些在MySQL中常用的SQL提示。
引用
1. USE INDEX
在查詢語句中表名的後面,添加USE INDEX 來提供希望MySQL去參考的索引列表,就可以讓MySQL不再考慮其他可用的索引。
引用
- explain select * from sales2 use index (ind_sales2_id) where id 3 \G;
2. IGNORE INDEX
如果用戶只是單純地想讓MySQL忽略一個或者多個索引,則可以使用IGNORE INDEX 作為HINT
3. FORCE INDEX
為強制MySQL使用一個特定的索引,可在查詢中使用FORCE INDEX作為HINT。例如當不強制使用索引的時候,因為id的值都是大於0的,因為MySQL會默認進行全表掃描,而不使用索引。例如:
引用
- expalin select * from sales2 where id > 0 \G;
但是,當使用FORCE INDEX進行提示時,即便使用索引的效率不是很高,MySQL還是選擇使用了索引,這是MySQL留給用戶的一個自行選擇執行計劃的權利。加入FORCE INDEX提示後在執行上面的SQL
引用
- explain select * from sales2 force index(index_sales2_id) where id > 0 \G;