关于内连接的缓慢where子句

时间:2014-08-15 20:46:20

标签: mysql sql innodb

SELECT journey.id
FROM journey
JOIN journey_day ON journey_day.journey = journey.id
JOIN service ON journey.service = service.id
JOIN operator ON operator.id = service.operator
JOIN pattern ON pattern.id = journey.pattern
JOIN pattern_link pl ON pl.section = pattern.section AND pl.from_stop = "370023292"
JOIN pattern_link pl2 ON pl2.section = pl.section AND pl2.from_sequence < pl.from_sequence
WHERE CURDATE() BETWEEN service.date_start and service.date_end AND operator.id = "TMTL"
Above is an SQL query that takes on average 0.1 - 0.3 seconds to run.

出于某种原因,只要我将AND journey_day.day = 3附加到WHERE子句,它就会为执行时间增加额外的4秒。因此我发布了这个问题。

journey_day表中的每一列都有某种索引。

id(INT 11) | journey(VARCHAR 128) | day(TINYINT 1)

id是主键,旅程和日期列都被编入索引。这个表完全没有问题,但是一旦WHERE子句对表格提出质疑,执行时间就会因为我的喜好而上升得太多了。

journey_day表就是确定行程运行的那一天。例如,如果旅程在星期三和星期四运行,那么旅程将在旅程列中具有其标识符,然后是3,在另一行中具有相同的标识但是具有4。

为什么会出现这么大的执行时间延迟?

查询前面的EXPLAIN结果:http://i.imgur.com/QrjZEHy.png

1 个答案:

答案 0 :(得分:0)

检查已编入索引或已调整的字段数。最有可能的是,journey_day.day没有编入索引,这使得对它的过滤非常缓慢。

检查查询的方法之一是在其上运行[EXPLAIN][1](在MySQL控制台中):

EXPLAIN <yourquery>

它将为您提供有关查询运行方式,要检查的行数以及是否使用相关表中的索引的详细计划。

您还可以执行的操作(可能帮助但无法保证)将整个查询包装到该过滤器中,以便将其应用于第一个查询的结果。

SELECT journey.id FROM (
SELECT journey.id id, journey_day.day jday
FROM journey
JOIN journey_day ON journey_day.journey = journey.id
JOIN service ON journey.service = service.id
JOIN operator ON operator.id = service.operator
JOIN pattern ON pattern.id = journey.pattern
JOIN pattern_link pl ON pl.section = pattern.section AND pl.from_stop = "370023292"
JOIN pattern_link pl2 ON pl2.section = pl.section AND pl2.from_sequence < pl.from_sequence
WHERE CURDATE() BETWEEN service.date_start and service.date_end AND operator.id = "TMTL") qq
WHERE qq.jday=3;