我有一张超过660万行的表。
我有一个名为trip_id
的字段,位于BINARY(16)
。我发现我的查询太慢(0.2 seconds
)。此查询每3秒运行一次。
在做任何愚蠢的事情之前,我想知道我是否将trip_id
上的索引大小从完全降低到12,它会有所作为吗?
如果我尝试更多地调整我的查询,它会有所作为吗?
由于
编辑:
查询:
SELECT stop_times.stop_id
FROM trips
LEFT JOIN stop_times ON trips.trip_id = stop_times.trip_id
WHERE trips.route_id = '141'
GROUP BY stop_times.stop_id
ORDER BY trips.trip_headsign ASC,
stop_times.stop_sequence ASC
trip_id BINARY(16)
route_id SMALLINT(3)
trip_headsign VARCHAR(50)
stop_sequence SMALLINT(3)
解释查询:
答案 0 :(得分:2)
经过研究,我发现了问题,因为是的,0.2秒很慢。
SELECT t.trip_headsign, st.stop_sequence, s.stop_code, s.stop_name
FROM stop_times AS st
JOIN stops AS s USING (stop_id)
JOIN ( SELECT trip_id,
route_id,
trip_headsign
FROM trips
WHERE route_id = '141'
LIMIT 2
) AS t
WHERE t.trip_id = st.trip_id
GROUP BY st.stop_id
首先,LEFT JOIN
取代JOIN
,而不是{{1}}。但重要的是,我在WHERE声明中匹配了所有结果。
但是,由于公交车只能有2个方向,我只需要将结果限制为2.现在,我的结果接近0.018。超过1000%的改善。
答案 1 :(得分:1)
你的'额外'栏中有'使用临时'和'使用filesort'。
这些是你可以改善事情的万无一失的迹象。这些出现的原因是因为你的GROUP和ORDER条款。
第一步:他们真的有必要吗?您可能会发现,端到端使用消耗此数据的语言对它们进行排序会更便宜。
第二步:如果您仍然需要ORDER BY
,请查看MySQL文档中的ORDER BY Optimization。索引未在此处进行排序的原因是GROUP BY
和ORDER BY
条款不同。
在盒子外面思考。您没有进行任何聚合,因此可能不需要分组。也许只需拉出所有行,然后忽略重复的ID。
答案 2 :(得分:0)
尝试将trip_headsign添加到“路线”索引中。因为您在ORDER BY中使用它,所以mysql需要转到实际的表来为它在与route_id匹配的索引中找到的每个记录获取它。如果在解释的Extra列中没有看到“Using index”,则表示MySQL被迫返回实际表以获取其他信息。