【发布时间】:2020-04-16 17:50:49
【问题描述】:
查询非常简单,即
SELECT
col1 , date_col
FROM table USE INDEX (device_date_col)
WHERE
device_id = "some_value"
AND date_col BETWEEN "2020-03-16 00:00:00" and "2020-04-16 00:00:00"
limit 1000000 ;
但第一次运行时最终返回结果需要 30 到 60 秒。然后它在 10 秒内返回结果。另一个问题是,当我再次更改 device_id 时,需要很长时间。除了使用正确的索引之外,我无法理解为什么会发生这种情况。
我们知道,由于我们的 API 遇到超时,API 网关有 30 秒的限制。从今天起突然发生。
主要目标是检索微小的数据,它返回的数据较少但也需要很长时间,即
....
AND col1 IS NOT NULL
GROUP BY
DATE(date_col),
HOUR(date_col),
MINUTE(date_col)
以下是一些有用的信息
- AWS RDS 具有实例 db.m4.large(vCPU 2 和 RAM 8GB)。
- MySql 版本 5.6.x
- date_col 和 device_col 上的复合索引
- 使用 InnoDB
- 表没有id字段(主键)
- 表中的总行数为 750 万
- 每台设备每 3 秒有一次数据
- 查询返回大约 600k 的行
- 解释查询显示它正在使用索引
更新
MySql Workbench 显示,当我在没有 group by 的情况下运行查询时,执行需要 2 秒,但检索时间 > 30 秒,当我使用 group by 时,服务器需要 > 30 来执行但检索需要 2 秒。
我认为我们需要更多
CPU 使用 group by 处理数据更多内存用于提取所有数据(无分组)
下图显示了没有分组依据的查询响应。查看持续时间/获取时间
【问题讨论】:
-
你试过不使用索引吗?您处于它对您的情况有用的边缘,请参见例如here。尝试删除
USE INDEX (device_date_col),或者,最有希望的是,在索引中包含 col1,例如添加索引(device_id, date_col, col1)。第二次运行比第一次运行更快是由于数据在内存中,而不必从磁盘读取。除了增加缓冲池(这可能需要您获得更多内存)或确保所有数据都在内存中(通过之前使用它)之外,您无能为力。 -
@Solarflare 我已经更新了问题,请您查看并建议我的假设?
-
我们已经确保第一个查询不应该超时,即它必须在 30 秒以下。
-
SQL_NO_CACHE 未按预期工作。每次我运行查询时,时间总是比以前少,这让我相信它仍然显示缓存的结果。还尝试了 RESET QUERY CACHE;刷新查询缓存;
-
@Solarflare,我已经按照您的建议创建了新索引(device_id、date_col、col1)。在有/没有 group by 的情况下,现在似乎工作正常。谢谢
标签: mysql amazon-rds database-performance query-performance sqlperformance