复杂查询

时间:2015-08-18 17:40:40

标签: mysql sql

我正在开发一个应用程序(使用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服务器的连接”消息。

为了更好地说明我在这里要完成的是表格如何:

旅行(并非显示所有列)

trips table

停止

all columns shown

城市(并非显示所有列)

cities table

基本上货轮插入行程并详细说明其停靠点,然后代理商将在可用的行程中进行搜索。因此,如果货轮发布行程A-> B-> C-> D-> E,则另一货轮发布行程K-> H-> E-> D-> C当代理人寻找C-> E时,两次旅行都应该出现。停靠表中的“序数”列是我后来过滤出错误方向的行程的方式。

什么可以延长响应时间?如何重写此查询以使其更快?

2 个答案:

答案 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
;

如果您可以使用适当的索引,这应该运行得非常快......