我正在排除查询性能问题。explain提供了一个预期的查询计划:

mysql> explain select * from table1 where tdcol between '2010-04-13 00:00' and '2010-04-14 03:16';
+----+-------------+--------------------+-------+---------------+--------------+---------+------+---------+-------------+
| id | select_type | table              | type  | possible_keys | key          | key_len | ref  | rows    | Extra       |
+----+-------------+--------------------+-------+---------------+--------------+---------+------+---------+-------------+
|  1 | SIMPLE      | table1             | range | tdcol         | tdcol        | 8       | NULL | 5437848 | Using where |
+----+-------------+--------------------+-------+---------------+--------------+---------+------+---------+-------------+
1 row in set (0.00 sec)

这是有意义的,因为使用了名为tdcol(KEY tdcol (tdcol))的索引,应该从该查询中选择大约500行。
但是,如果我只查询一分钟的数据,我们将得到以下查询计划:
mysql> explain select * from table1 where tdcol between '2010-04-13 00:00' and '2010-04-14 03:17';
+----+-------------+--------------------+------+---------------+------+---------+------+-----------+-------------+
| id | select_type | table              | type | possible_keys | key  | key_len | ref  | rows      | Extra       |
+----+-------------+--------------------+------+---------------+------+---------+------+-----------+-------------+
|  1 | SIMPLE      | table1             | ALL  | tdcol         | NULL | NULL    | NULL | 381601300 | Using where |
+----+-------------+--------------------+------+---------------+------+---------+------+-----------+-------------+
1 row in set (0.00 sec)

优化器相信扫描会更好,但它需要检查的行数超过70倍,所以我很难相信表扫描会更好。
此外,“use key tdcol”语法不会更改查询计划。
提前感谢您的帮助,我非常乐意提供更多信息/回答问题。

最佳答案

500万个索引探测可能比读取所有3.5亿行(顺序磁盘读取)更昂贵(大量随机磁盘读取,可能更复杂的同步)。
这种情况可能是一个例外,因为时间戳的顺序大概与插入表的顺序大致匹配。但是,除非tdcol上的索引是“聚集”索引(意味着数据库确保底层表中的顺序与tdcol中的顺序匹配),否则优化器不太可能知道这一点。
在没有顺序相关信息的情况下,假设您想要的500万行大致均匀地分布在3.5亿行中是正确的,因此索引方法将涉及读取基本行中的大部分或几乎所有页面(在其中如果扫描要比索引方法便宜得多,那么直接和连续的读取要比随机读取少得多。

关于mysql - 为什么带有InnoDB的MySQL在 key 存在时进行表扫描并选择检查70多行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2642108/

10-11 21:23