我正在开发一个应用程序(使用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时,两次旅行都应该出现。停靠表中的“序数”列是我后来过滤出错误方向的行程的方式。
什么可以延长响应时间?如何重写此查询以使其更快?
答案 0 :(得分:1)
如果我理解您的查询权限,您似乎正在尝试检索两个城市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;
或者我可能完全误解了你要做的是什么,在这种情况下我会删除这个答案。
答案 1 :(得分:0)
我想说你可以将你的查询重新写入
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`)
INNER JOIN stops as `stops` ON trips.trip_id = stops.trip_id
WHERE stops.city_id IN (7583, 7565) -- all stops in this 2 cities
;
如果您可以使用适当的索引,这应该运行得非常快......