我们正在努力解决一个只在第一次调用时才会发生的慢查询。之后查询速度更快。 查询第一次完成时,需要15-20秒。后续调用采取< 1.5秒但是,如果几个小时没有再次调用,则查询将再次花费15-20秒。
该表是一个名为system(外键)的实体的每日读数表,包含系统ID,日期,样本读数以及读数是否完成(过去)的指示。该查询要求200个选定系统的1年样本(365天)范围。
看起来像这样:
SELECT system_id,
sample_date,
reading
FROM Dailyreadings
WHERE past = 1
AND reading IS NOT NULL
AND sample_date < '2014-02-25' AND sample_date >= DATE('2013-01-26')
AND system_id IN (list_of_ids)
list_of_ids表示我们想要读数的200个系统ID的列表。
我们有一个关于system_id,sample_date和两者的索引的索引。查询的结果通常会返回~70,000行。当在查询上使用说明时,我可以看到使用索引,并且规划只会超过~70,000行。
MySQL在亚马逊RDS上。所有表的引擎都是innodb。
Dailyreadings表有大约6千万行,所以它非常大。但是我无法理解一个非常简单的范围查询,最多可能需要20秒。这是在只读副本上完成的,因此并发写入不是我猜的问题。这也发生在DB的暂存副本上,该副本几乎没有同时发生的读/写请求。
在阅读了许多关于慢速首次查询的问题后,我认为问题是第一次需要从磁盘读取查询,然后缓存。但是,我不明白为什么这么简单的查询需要花费这么多时间从磁盘读取。我也尝试过对innodb参数的许多调整,并且无法改进。即使加倍系统内存似乎也没有帮助。
关于可能出现什么问题的任何指示?以及我们如何改善第一次查询所需的时间?任何想法如何查明确切的问题?
答案 0 :(得分:0)
查询运行后运行速度很快,因为mysql可能正在缓存它。要查看您的查询如何在禁用缓存的情况下运行,请尝试:SELECT SQL_NO_CACHE system_id ...
另外,我发现将表格上的日期与大量数据进行比较会对性能产生负面影响。在可能的情况下,我使用unix时间戳将日期保存为整数并比较日期,并且工作得更快。