SELECT SQL_NO_CACHE TIME_FORMAT(ADDTIME(journey.departure
, SEC_TO_TIME(SUM(link2.elapsed))), '%H:%i') AS departure
FROM journey
JOIN journey_day
ON journey_day.journey = journey.code
JOIN pattern
ON pattern.code = journey.pattern
JOIN service
ON service.code = pattern.service
JOIN link
ON link.section = pattern.section
AND link.stop = "370023591"
JOIN link link2
ON link2.section = pattern.section
AND link2.id <= link.id
WHERE journey_day.day = 6
GROUP BY journey.id
ORDER BY journey.departure
以上查询需要1-2秒才能运行。我需要将其减少到大约100毫秒。请注意,我了解查询中未使用service
表,但这只是为了简化问题。
我有什么想法可以加快速度吗?我可以看到链接表正在使用filesort,这是否会导致查询缓慢?
答案 0 :(得分:0)
有一种想法是你可以用最小的“id”值明确地优化“链接”表记录的选择。
使用临时表或物化WITH语句是生成结果集的两种方法。获得“id”的最小值的两种方法是1)按id排序,添加row_number并选择第一个值;或者2)我使用一个带窗口的row_number,按id排序,然后再次选择值为1的行。
答案 1 :(得分:0)
精心策划的索引对性能至关重要。根据您提供的内容,我将从以下特定索引开始......这些索引都涵盖索引,以限定您将使用的所有联接和条件。覆盖索引可以帮助引擎,因为引擎可以获得符合条件的所有数据,而无需转到原始数据页。
最具体地说,从您的旅程表开始,我将按照我拥有的顺序显示基于所有3个字段的综合索引......第一天,因为那是您的WHERE标准,然后是ID,因为它是GROUP BY最后是您的ORDER BY子句的DEPARTURE。
LINK表基于section并首先停止,因为这些是加入旅程表的条件。下一个ID,因为它是加入LINK2的基础,最后是ELAPSED,用于您的现场标准选择。
table index
journey (day, id, departure)
link (section, stop, id, elapsed)
pattern (code, service, section)
service (code)