为什么使用InnoDB的MySQL在存在键时选择进行表扫描并选择检查70倍以上的行?

为什么使用InnoDB的MySQL在存在键时选择进行表扫描并选择检查70倍以上的行?,第1张

概述我正在对查询性能问题进行故障排除.这是来自explain的预期查询计划:mysql> explain select * from table1 where tdcol between '2010-04-13 00:00' and '2010-04-14 03:16'; +----+-------------+--------------------+-

我正在对查询性能问题进行故障排除.这是来自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倍以上的行? 所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1165642.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存