mysql 5.1中開始引入optimizer_switch, 控制mysql優化器行為。他有一些結果集,通過on和off控制開啟和關閉優化器行為。使用有效期全局和會話兩個級別,在5.5中optimizer_swtich 可取結果如下,不同mysql版本可取結果不同。5.1和5.6參考官方文檔。
mysql> select @@optimizer_switch;
+------------------------------------------------------------------------------------------------------------------------+
| @@optimizer_switch |
+------------------------------------------------------------------------------------------------------------------------+
| index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on |
+------------------------------------------------------------------------------------------------------------------------+
在mysql優化語句過程中,可通過設置optimizer_switch控制優化行為。
在我們生產環境上,某天mysql服務器壓力特別大,load一度達到了100,查詢發現數據庫中有大量的sql語句state 狀態result sorting ,result sorting這種排序特別消耗cpu和內存資源。抽取其中的一條sql查看執行計划
mysql> explain selectproduct_id,main_product_id,is_main_product,external_product_id from product where shop_id = '5939' AND status in ('0') AND main_product_id in ('0') AND product_type in ('0','1') order by operator_datedesc limit 800,100;
+----+-------------+----------------+-------------+---------------------------------------------+--------------------------------+---------+------+------+------------------------------------------------------------------------------+
| id | select_type |table |type |possible_keys |key | key_len | ref | rows |Extra |
+----+-------------+----------------+-------------+---------------------------------------------+--------------------------------+---------+------+------+------------------------------------------------------------------------------+
| 1 |SIMPLE | product_common |index_merge | main_product_id,shop_id,status,product_type |shop_id,main_product_id,status | 5,5,5 | NULL | 810 | Usingintersect(shop_id,main_product_id,status); Using where; Using filesort
type類型是 index_merge(索引合並排序)。業務需要或濫建索引,數據表上會建很多索引。針對這個查詢,可以通過修改optimizer_switch來優化優化器行為:
set global optimizer_seitch="index_merge=off"
這個方式也行會有一定風險,影響其他sql,在服務器端操作要謹慎
另外一種方式:如果建立的索引不合理,可以建立復合索引,然后刪掉這些單列索引,這樣sql效率也會提高。本身index_merge提高查詢效率,由於本身的特點,可能會引起性能問題,那么,應該建立復合索引還是單列索引,這篇文章《multi-column-indexes-vs-index-merge》寫的很好。