返回大约 12000 行后的 MySQL 慢查询

Posted

技术标签:

【中文标题】返回大约 12000 行后的 MySQL 慢查询【英文标题】:MySQL Slow query after approx 12000 rows returned 【发布时间】:2015-07-12 23:37:06 【问题描述】:

我有一张桌子: power_ref INT 主键 瓦 INT 时间日期时间

有几百万行,基本上是我家每六秒一次的耗电量。

要生成一天条目的图表,我有以下查询(稍作修改,因为我真的用 now() 替换了手动输入的日期):

"select watts as Watts, time as Time from power where date(time)=date('2015-07-10') order by time desc limit 14400;"

“时间”列上有一个索引,但此查询忽略了它。运行大约需要 15 秒。

但是,如果我发出以下命令:

"select watts as watts, time as time from power where date(time)=date('2015-07-10') order by time desc limit 12000;"

查询大约在 0.1 秒内完成,mysql 使用时间列上的索引。

我尝试了以下(强制使用索引,但 MySQL 仍然不会使用索引)

"select watts, time from power USE INDEX (timeIndex) where date(time)=date('2015-07-10') order by time desc limit 14400;"

我通过在查询前面发出“解释”来确定是否使用了索引。

我设置了 14400 的限制,因为这是一天中的最大条目数,不是真的需要,但以防万一。

【问题讨论】:

添加两个查询的说明:14400和12000的限制,可能有助于理解问题。 它不会使用索引,因为它需要将 date() 函数应用于每一行。尝试执行相同的查询,但不将日期函数应用于列,而是将时间添加到比较值,以正确的 YYYY-MM-DD H:i:s 格式,再次,没有日期函数,因为它不需要. 【参考方案1】:

优化器确定全表扫描会更快。一旦数据量发生变化,这种行为就会发生变化。 USE INDEX 不是强制索引,而是强制 mysql 忽略其他索引。 FORCE INDEX 将强制使用索引:

select watts, time from power FORCE INDEX (timeIndex) 
where date(time)=date('2015-07-10') order by time desc limit 14400;

应该得到你想要的索引行为

【讨论】:

这确实给了我索引行为 - 它似乎也揭示了 MySQL 不使用索引的原因 - 当我现在运行查询时,它在 ~0.3 秒内执行,但是第一次运行,提取需要一分钟。似乎存在缓存问题 - 有什么想法吗? 获取:你能澄清一下吗?如果查询运行 0.3 秒,那应该包括获取记录的时间。输出到 14k 条记录的显示器可能需要一段时间。我通常通过将数据放在临时表中或添加 SELECT COUNT(*) FROM (原始查询) a; 来对查询进行基准测试。强制获取所有记录 我一直在 MySQL 工作台中发出查询,它指定了两次——一次用于查询持续时间,一次用于获取。我的猜测是存在某种缓存大小问题,但我已经超出了我的深度...... 获取只是将记录从服务器复制到客户端。这仅受客户端的网络和/或 cpu 处理能力的影响:可以通过仅检索您使用的数据来优化它。大多数情况下可以忽略它以进行进一步优化。

以上是关于返回大约 12000 行后的 MySQL 慢查询的主要内容,如果未能解决你的问题,请参考以下文章

非常慢的 MySQL COUNT DISTINCT 查询,即使有索引——如何优化?

MySQL中like查询速度慢的问题

mysql查询慢--2小时+

中 MySQL 表的慢查询(100 万行)

慢查询分组,加入MYSQL laravel

如何解决mysql 查询和更新速度慢