mysql參數optimizer_switch 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效率也會提高。