問題
生成環(huán)境励七,同一條sql在不同的從庫執(zhí)行智袭,產(chǎn)生的執(zhí)行計(jì)劃不同,一個使用了索引掠抬,一個未使用索引
explain SELECT * FROM `database`.`table` FORCE INDEX(create_time) WHERE create_time >= 1508360400 and create_time <= 1508444806 ORDER BY create_time asc LIMIT 4000, 1000;
原因分析
- 分析是否是取值limit太大补履,超過count的1/3,Innodb引擎不使用索引剿另。經(jīng)分析共計(jì)有6000多條數(shù)據(jù),索引這個原因可以排除
- 相同的sql在不同的從庫執(zhí)行,一個未使用索引雨女,分析是索引文件或者表的碎片導(dǎo)致谚攒,后咨詢阿里DBA給分析是表的碎片問題導(dǎo)致產(chǎn)生的執(zhí)行計(jì)劃不正常
解決方案
方案1:執(zhí)行
OPTIMIZE TABLE
修復(fù)碎片或者執(zhí)行ALTER TABLE foo ENGINE=InnoDB
,以上兩種操作都會鎖表氛堕,對于數(shù)據(jù)量大馏臭,且業(yè)務(wù)高峰期執(zhí)行需要慎重-
方案2:強(qiáng)制索引,也就是
FORCE index create_time
讼稚,強(qiáng)制mysql 引擎使用索引括儒,這里需要注意一下,當(dāng)使用強(qiáng)制索引時锐想,存儲引擎會檢查強(qiáng)制索引是否可用帮寻,如果不可用,還需要掃描表來判斷那種執(zhí)行計(jì)劃赠摇,官方說明:The FORCE INDEX hint acts like USE INDEX (index_list), with the addition that a table scan is assumed to be very expensive. In other words, a table scan is used only if there is no way to use one of the named indexes to find rows in the table.
也不用擔(dān)心有副作用固逗,如果強(qiáng)制索引可用,正好能提要索引選擇的效率
參考鏈接: