我收到了这个查询。这需要〜 0.0854 秒。我发现它有点慢。下面看我的解释
SELECT
stops.stop_number,
stops.stop_name_1,
stops.stop_name_2
FROM
tranzit.stops_times
INNER JOIN
tranzit.stops
ON
(
stops_times.stop_id = stops.stop_id
)
INNER JOIN
tranzit.trips
ON
(
stops_times.trip_id = trips.trip_id
)
WHERE
trips.route_id = 109 AND
trips.trip_direction = 1 AND
trips.trip_period_start <= "2011-11-24" AND
trips.trip_period_end >= "2011-11-24"
GROUP BY
stops.stop_id
ORDER BY
stops_times.time_sequence ASC
LIMIT
0, 200
解释
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE trips index_merge trip_id,trip_period_start,trip_period_end,trip_dir... route_id,trip_direction 3,1 NULL 271 Using intersect(route_id,trip_direction); Using wh...
1 SIMPLE stops_times ref stop_id,trip_id trip_id 16 tranzit.trips.trip_id 24
1 SIMPLE stops ref stop_id stop_id 3 tranzit.stops_times.stop_id 1 Using where
我有旅行指数:
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
trips 1 agency_id 1 agency_id A 2 NULL NULL BTREE
trips 1 trip_id 1 trip_id A 9361 NULL NULL BTREE
trips 1 trip_period_start 1 trip_period_start A 2 NULL NULL BTREE
trips 1 trip_period_end 1 trip_period_end A 2 NULL NULL BTREE
trips 1 trip_direction 1 trip_direction A 2 NULL NULL BTREE
trips 1 route_id 1 route_id A 106 NULL NULL BTREE
trips 1 shape_id 1 shape_id A 520 NULL NULL BTREE
trips 1 trip_terminus 1 trip_terminus A 301 NULL NULL BTREE
停止指数
stop_number BTREE Non Non stop_number 4626 A
agency_id BTREE Non Non agency_id 1 A
stop_id BTREE Non Non stop_id 4626 A
感谢您的帮助
答案 0 :(得分:1)
考虑到表中有多少行,它已经很快运行了。您可以尝试一些不同的方法,例如在条件或执行简单选择时添加更多,然后运行第二个查询以获取所需的连接字段。但这些并不是你真正需要关注的地方。
重要的问题是这个查询将如何在野外表现。如果你每秒运行100次,你需要知道它是否会降级并成为瓶颈。如果它每次都可以在0.08运行,那么它仍然允许响应非常快的应用程序。
然而,最重要的策略是,如果可能并且有效,则使用memcache或类似选项来阻止始终运行查询。
答案 1 :(得分:1)
正如人们之前写的那样:
拆分为2个查询:
SELECT group_concat(trip_id) FROM trips WHERE trips.route_id = 109 AND trips.trip_direction = 1 AND trips.trip_period_start = "2011-11-24"
SELECT stops.stop_number, stops.stop_name_1, stops.stop_name_2 FROM tranzit.stops_times, tranzit.stops WHERE stops_times.stop_id = stops.stop_id AND stops_times.trip_id in ( ...) GROUP BY, ...
我认为它会更快,因为你不需要查询之外的旅行表中的其他信息。
答案 2 :(得分:0)
最棘手的部分是范围查询trip_period_start, trip_period_end
,
我认为你可以考虑一个复合键,如: -
alter table trips
add index testing
(
route_id, trip_direction, trip_period_start, trip_period_end
);
取决于trip_direction的唯一值,
如果总是只有几个独特的值,
alter table trips
add index testing
(
route_id, trip_period_start, trip_period_end, trip_direction
);
答案 3 :(得分:0)
已经不到十分之一秒,你想要更快吗?好... 我会在(route_id,trip_direction,trip_period_start)上构建一个复合索引,因为它们是查询的三个关键元素。此外,按顺序将最小粒度放在索引的前面(特定路径)。然后,在那之内,它的方向,然后,日期。接下来,由于您正在进行INNER连接,因此我会先将查询的顺序与trip表进行交换。另外,在TRIP_ID上的“stops_times”表上有一个索引。通过从第一个表及其限定符开始,然后通过关系连接到子级别的tabl,您仍然可以获得元素,但是您在出行时首先针对最小的索引集运行。
select STRAIGHT_JOIN
stops.stop_number,
stops.stop_name_1,
stops.stop_name_2
from
tranzit.trips
join tranzit.stops_times
on trips.trip_id = stops_times.trip_id
join tranzit.stops
on stops_times.stop_id = stops.stop_id
where
trips.route_id = 109
AND trips.trip_direction = 1
AND trips.trip_period_start <= "2011-11-24"
AND trips.trip_period_end >= "2011-11-24"
group by
stops.stop_id
ORDER BY
stops_times.time_sequence
LIMIT
0, 200
答案 4 :(得分:0)
我发现了一些像魅力一样的东西。我的结果编号是:
这些结果不是来自缓存。我在t
(trips.agency_id
,trips.route_id
,trips.trip_direction
,trips.trip_period_start
,trips.trip_period_end
)中切换了所有 WHERE ,并且它工作得很好!我无法解释为什么,但如果有人可以,我想知道为什么。非常感谢大家!
PS:即使没有trips.agency_id
,它的效果也很好。
SELECT
stops.stop_number,
stops.stop_name_1,
stops.stop_name_2
FROM
tranzit.stops_times,
tranzit.stops,
(
SELECT
trips.trip_id
FROM
tranzit.trips
WHERE
trips.agency_id = 5 AND
trips.route_id = 109 AND
trips.trip_direction = 0 AND
trips.trip_period_start <= "2011-12-01" AND
trips.trip_period_end >= "2011-12-01"
LIMIT 1
) as t
WHERE
stops_times.stop_id = stops.stop_id AND
stops_times.trip_id in (t.trip_id)
GROUP BY
stops_times.stop_id
ORDER BY
stops_times.time_sequence ASC
LIMIT
0, 200
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1 Using temporary; Using filesort
1 PRIMARY stops_times ref trip_id,stop_id trip_id 16 const 33 Using where
1 PRIMARY stops ref stop_id stop_id 3 tranzit.stops_times.stop_id 1 Using where
2 DERIVED trips ref testing testing 4 275 Using where