我正在对查询性能问题进行故障排除.这是来自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))的索引,因此应从该查询中选择大约5M行.
但是,如果我仅查询一分钟的数据,我们将得到以下查询计划:
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亿行中,因此索引方法将涉及读取页面中的大部分或几乎所有页面.无论如何,底层行(在这种情况下,扫描将比索引方法便宜得多,直接读取和顺序读取的次数要少于随机读取的次数).
总结以上是内存溢出为你收集整理的为什么使用InnoDB的MySQL在存在键时选择进行表扫描并选择检查70倍以上的行? 全部内容,希望文章能够帮你解决为什么使用InnoDB的MySQL在存在键时选择进行表扫描并选择检查70倍以上的行? 所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)