改进索引以加快查询速度

时间:2015-03-01 10:21:00

标签: mysql sql

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表,但这只是为了简化问题。

enter image description here

我有什么想法可以加快速度吗?我可以看到链接表正在使用filesort,这是否会导致查询缓慢?

2 个答案:

答案 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)