sqlcli> explain SELECT * FROM cms_article_nav WHERE navmodel_id IN (162,163,164 ,165,166,167,168,169,170,171) \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: cms_article_nav type: ALL possible_keys: nav key: NULL key_len: NULL ref: NULL rows: 279 Extra: Using where 1 row in set (0.00 sec)
这表就两个字段,没主键,navmodel_id列建了索引。 用explain执行, possible_keys: nav,说明有可用的索引, 但实际没有用,type是ALL,说明走的全表扫描。
尝试把select * 换掉,如下:
sqlcli> explain SELECT navmodel_id FROM cms_article_nav WHERE navmodel_id IN (1 62,163,164,165,166,167,168,169,170,171) \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: cms_article_nav type: range possible_keys: nav key: nav key_len: 4 ref: NULL rows: 59 Extra: Using where; Using index 1 row in set (0.00 sec)
这回走了索引~~
复制该表,插入20万条数据,重新执行:
sqlcli> explain SELECT * FROM cms_article_nav_copy WHERE navmodel_id IN (162,16 3,164,165,166,167,168,169,170,171) \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: cms_article_nav_copy type: range possible_keys: nav key: nav key_len: 4 ref: NULL rows: 69 Extra: Using where 1 row in set (0.00 sec)
这回走了索引。
分析一下原因: -------------------------- 开始,数据太少,还是select *, mysql认为先从索引找,再去表里取其它字段的数据, 比较费事,不如直接从表里找快,所以, 看到了索引,也没用,走的全表扫描。
当数据变为20万时,通过索引,就快得多了, 所以走的索引。
走不走索引,是mysql根据数据量、值的分布情况等因素动态判断的~~ -------------------------------- 这个sql就没必要优化了,数据量少时,全表扫描也很快,多了走索引也很快。
|