一个关于explain出来为all的说明及优化

 explain sql语句一个语句,得到如下结果,为什么已经创建了t_bill_invests.bid_id的索引,但却没有显示using index,而是显示all扫描方式呢,原来这还与select里面的内容有关

 
真正执行此语句所用的时间:
17:08:20     SELECT t_bill_invests.`receive_corpus`, t_bill_invests.`receive_interest`, t_bids.`period`, t_bill_invests.`receive_time`,  `t_bids`.`title` AS `title`, `t_bids`.`period_unit` AS `period_unit` FROM `t_bill_invests`  LEFT JOIN `t_bids` ON `t_bids`.`id` = `t_bill_invests`.`bid_id` LEFT JOIN t_invests ON t_bill_invests.`invest_id` = `t_invests`.`id` WHERE `t_bill_invests`.`status` = -1 AND `t_invests`.`transfer_status` <> - (1) AND t_invests.user_id = 3 ORDER BY t_bill_invests.receive_time ASC LIMIT 5     5 row(s) returned     23.728 sec / 0.000 sec
 
 
 
我们先来做几个小实验来说明此问题,如下,我们在user_id与bid_id上都是有索引的,但是explain出来的结果却不一样:
 
这是因为user_id并没有在条件语句中,mysql会通过bid_id找到相关的值,再进一步回表扫描,故会显示为all,但此时的扫描已经不是真的全表扫描,而是根据条件中筛选出来的值再来找到对应的user_id
进一步的,如果我们添加一个覆盖索引:
 
 
 
 
可以发现,现在虽然是select user_id但也可以走索引了。
 
一个问题是我们并不能把所有的select里面的列都添加为覆盖索引,所以我们只要保证条件里面所涉及的列有相应的索引,这个速度都会是非常快的。
 
通过检查这条语句,发现t_bill_invests.`invest_id`这一列还没有添加索引,故我们添加上:
alter table t_bill_invests add index index_bill_inv_invest_id(invest_id)
 
 
再次执行:
 
真正执行的时间:
17:12:38     SELECT t_bill_invests.`receive_corpus`, t_bill_invests.`receive_interest`, t_bids.`period`, t_bill_invests.`receive_time`,  `t_bids`.`title` AS `title`, `t_bids`.`period_unit` AS `period_unit` FROM `t_bill_invests` LEFT JOIN `t_bids` ON `t_bids`.`id` = `t_bill_invests`.`bid_id` LEFT JOIN t_invests ON t_bill_invests.`invest_id` = `t_invests`.`id` WHERE `t_bill_invests`.`status` = -1 AND `t_invests`.`transfer_status` <> - (1) AND t_invests.user_id = 3 ORDER BY t_bill_invests.receive_time ASC LIMIT 5     5 row(s) returned     1.763 sec / 0.000 sec
 
 
可以发现,时间已经大大减少了,目标完成。
 
posted @ 2015-08-10 18:18  泽锦  阅读(1803)  评论(0编辑  收藏  举报