对大型MySQL表进行简单查询一开始需要很长时间,以后要快得多

时间:2014-02-27 11:49:38

标签: mysql performance amazon-rds

我们正在努力解决一个只在第一次调用时才会发生的慢查询。之后查询速度更快。 查询第一次完成时,需要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参数的许多调整,并且无法改进。即使加倍系统内存似乎也没有帮助。

关于可能出现什么问题的任何指示?以及我们如何改善第一次查询所需的时间?任何想法如何查明确切的问题?

  • 编辑 似乎问题可能在IN子句中,因为列表是大(200)个项目,所以它很慢。这是一个已知的问题?有没有办法加速这个?

1 个答案:

答案 0 :(得分:0)

查询运行后运行速度很快,因为mysql可能正在缓存它。要查看您的查询如何在禁用缓存的情况下运行,请尝试:SELECT SQL_NO_CACHE system_id ...

另外,我发现将表格上的日期与大量数据进行比较会对性能产生负面影响。在可能的情况下,我使用unix时间戳将日期保存为整数并比较日期,并且工作得更快。