我正在开发一个应用程序(使用 CodeIgniter),需要使用相当复杂的查询来检索行程。这是一个例子:
SELECT *, CONCAT(`u1`.`city`,', ', `u1`.`country_id`) as `from_city`,
CONCAT(`u2`.`city`,', ', `u2`.`country_id`) as `to_city`
FROM trips
LEFT JOIN `cities` as `u1` ON (`u1`.`id`=`from_city`)
LEFT JOIN `cities` as `u2` ON (`u2`.`id`=`to_city`)
WHERE trip_id
IN (SELECT trip_id
FROM stops
WHERE city_id = 7583
AND trip_id
IN (SELECT trip_id
FROM stops
WHERE trip_id
IN (SELECT trip_id
FROM stops
WHERE city_id=7565)))
ORDER BY departure_date;
直到今天它都工作得很好。它涉及 3 个表(行程、停靠站和城市)。自开始测试以来,行程和停靠表并没有增加太多,可能从 200 条记录增加到 300 条记录。
如果我在 CodeIgniter 应用程序中进行测试,我会收到 2006 或 2013“与 MySQL 服务器的连接丢失...”错误。如果我使用 NaviCat 进行查询,我会收到相同的“查询期间丢失与 MySQL 服务器的连接”消息。
为了更好地说明我在这里想要完成的任务,表格如下所示:
行程(未显示所有列)
停止
城市(未显示所有列)
基本上,货轮会插入行程并详细说明其停靠点,然后代理机构将在可用的行程中进行搜索。因此,如果一架货机发布了 A->B->C->D->E 的行程,另一架货机发布了 K->H->E->D->C 的行程,则当代理时,这两个行程都应该显示寻找 C->E。停靠站表中的“序数”列是我后来过滤掉方向错误的行程的方式。
什么可以将响应时间延长那么多?如何重写此查询以使其更快?
最佳答案
如果我正确理解您的查询,您似乎正在尝试检索 7583 和 7565 这两个城市之间的所有行程。
如果是这样,下面的查询应该返回相同的结果并且效率更高:
SELECT *, CONCAT(u1.city,', ', u1.country_id) as from_city,
CONCAT(u2.city,', ', u2.country_id) as to_city
FROM trips t1
LEFT JOIN cities as u1 ON (u1.id=from_city)
LEFT JOIN cities as u2 ON (u2.id=to_city)
JOIN (
SELECT trip_id FROM stops t1
WHERE city_id IN (7583, 7565)
GROUP BY trip_id
HAVING COUNT(DISTINCT city_id) = 2
) x ON t1.trip_id = x.trip_id
ORDER BY departure_date;
或者也许我完全误解了你想要做什么,在这种情况下我会删除这个答案。
关于MySQL 连接因复杂查询而丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32079161/