MySQL数据量对innodb索引使用的影响
从开始使用mysql起, 就觉得:
1. 索引的使用对innodb的性能的影响是很大的, 在做explain的时候, 当extra中出现了filesort的时候一般就意味者低效率和应当优化sql语句
2. 在select语句中, where中用到的条件字段order by中的字段最好是同一个(些)字段(假定只有都只有一个(些)字段), 且这个字段最好是有索引的, 这样在explain的时候, type就会是index, 且extra中不会有filesort; 如果where中的字段和order by的字段不一样的话, 则可能出现filesort, 从而会导致低效
在实际中遇到了一个例子, 发现上面的理解其实是比较片面的, 这个例子的大体情况是:
表t_mytable中有字段F_time_1和F_time_2,分别是datatime, 且分别都有索引;字段F_pid是主键
1. 运行sql语句 SELECT … FROM t_mytable WHERE F_pid=’val’ AND F_time_1>= ‘time1′ AND F_TIME_1 <= ‘time2′ ORDER BY F_time_1, 记录条目是12条, 但发现效率很低;觉得很奇怪:这个语句的效率应该高才对的
2. 尝试着改了一下sql语句为SELECT … FROM t_mytable WHERE F_pid=’val’ AND F_time_2>= ‘time1′ AND F_TIME_2 <= ‘time2′ ORDER BY F_time_1,记录条目是8条,效率很高;
效率上的差别让人觉得有些奇怪, 觉得是违反一直以来的直觉的, 于是再explain了两条语句, 对比了一下结果,发现一个很大的不一样是第一条语句type是index, rows的结果是100w级别; 而第二条语句的type为range, extra中有filesort, 但是rows那一栏大概10w级。想了一下, 问题应该在这个记录的数量上了:
1. 第一条语句中, where中字段和order by的字段一致,被优化成index类型, 但是由于F_time_1的区分度很低, 符合F_time_1条件的记录很多, 结果导致扫描索引很慢, 虽然省掉了filesort,但效率依旧很低
2. 第二条语句中, where中的字段和order by字段不一致, mysql采用了range扫描加filesort的方式, 这样以来,扫描的记录大大减少,虽然后面有个filesort, 但是由于符合条件的记录少, 内排序就得了, 结果效率反而高很多
总结如下:
1. explain的结果有时候会骗人的, 采用具有最优explain结果的语句效率不一定最好, 因为语句的执行效果受到数据量的影响
2. 在通过explain优化语句时, 需要把数据的区分度与考虑进来, 尽量使用区分度好的字段; 不要为了追求漂亮的explain的结果而建立区分度不大的索引来使用
