在 AWS Aurora MySQL 8.0 上运行
我有一个包含_record_id、location_id、visit_date的visit_data表。
我需要向查询提供 location_id 列表,并确定其中一个 location_id 是否是任何 record_id 的最后一次访问。
我确实有一个功能查询,可以在生产中运行,但性能非常慢。
SELECT
ud.record_id,
vd.location_id
FROM
user_data as ud
visit_data as vd
WHERE ud.record_id = vd._record_id
AND vd._campaign_id in (123)
AND vd.location_id = (SELECT
pvd.location_id
FROM
visit_data as pvd
WHERE
pvd._campaign_id in (123)
AND pvd._record_id = ud.record_id
AND pvd.location_id IN ('location-1', 'location-2',
'location-3', 'location-4',
'location-5', 'location-1800')
ORDER BY pvd.visit_date DESC
LIMIT 1)
AND vd.location_id IN ('location-1', 'location-2',
'location-3', 'location-4',
'location-5', 'location-1800')
AND vd.visit_date BETWEEN '2022-01-01' AND '2024-01-31'
GROUP BY ud.record_id
我确实得到了预期的结果,但是在一个只有 200 万多条记录的表上,它花费了 60 秒以上的时间。
我已经使用了所有索引的排列,包括record_id (rid)、campaign_id (cid)、poi 和visit_date,最后保留visit_date。我可以思考,但我似乎无法找到正确的组合。
选择类型 | 桌子 | 类型 | 可能的_key | 键 | key_len | 参考 | 行 | 过滤 | 额外 |
---|---|---|---|---|---|---|---|---|---|
小学 | rd | 范围 | _poi__访问日期__索引 | 770 | 105917 | 9.5 | 使用索引条件;使用地点;使用临时 | ||
小学 | FD | eq_ref | 小学 | 小学 | 4 | 1 | 100 | 使用索引 | |
依赖者 | PVD | 参考 | _cid__rid__索引 | 4 | 3 | 12.17 | 使用索引条件;使用地点;使用文件排序 |
我希望有一些我没有看到的策略逻辑,并使用其他人可能看到的正确查询结构。
我希望我提供了足够的信息来提供帮助。
谢谢 --FS
首先,我没有发表评论的权限,所以请理解我正在使用回复功能提出其他问题:)
由于我不知道似乎是查询目标表的
user_data
和visit_data
表的详细规格,因此似乎很难准确确定。我有一些疑问。两个表的PK是哪一列?这两个表是否受FK条件限制? visit_date
中当前是否存在唯一的索引(record_id、campaign_id、poi、visit_date)?
另外,我很好奇是否需要单独通过查询来检索所需的结果(基于访问日期的上次访问ID),以及是否可以在应用程序级别在某种程度上解决这个问题。