具有多个类似子选择的mysql update命令

具有多个类似子选择的mysql update命令,sql,mysql,Sql,Mysql,我编写了下面的更新命令,但是子选择中有冗余。我不是SQL方面的专家,希望您能帮助我提高查询效率。提前谢谢 update trips set origin = (select stop_name from stops inner join stop_times on stops.stop_id = stop_times.stop_id where stop_times.trip_id = trips.trip_id order by stop_

我编写了下面的更新命令,但是子选择中有冗余。我不是SQL方面的专家,希望您能帮助我提高查询效率。提前谢谢

update trips
  set origin = 
  (select stop_name 
    from stops 
    inner join stop_times
    on stops.stop_id = stop_times.stop_id
    where stop_times.trip_id = trips.trip_id
    order by stop_sequence asc
    limit 1) 
  ,
  destination = 
  (select stop_name 
    from stops 
    inner join stop_times
    on stops.stop_id = stop_times.stop_id
    where stop_times.trip_id = trips.trip_id
    order by stop_sequence desc
    limit 1)
  ,
  starts = 
  (select arrival_time
    from stop_times
    where stop_times.trip_id = trips.trip_id
    order by stop_sequence asc
    limit 1) 
  ,
  ends = 
  (select arrival_time
    from stop_times
    where stop_times.trip_id = trips.trip_id
    order by stop_sequence desc
    limit 1)
;
以下是相关的表格定义。大约有72K 行程、8K次停车和200万次停车。也许平均20?停止 每次旅行(只是猜测)


首先添加一个关于停止时间的索引,以包括trip\u id和stop\u sequence列

ALTER TABLE stop_times ADD PRIMARY KEY(trip_id, stop_sequence)
然后,尝试运行此更新:

update trips t JOIN (
    SELECT trip_id, MIN(stop_sequence) minS, MAX(stop_sequence) maxS 
    FROM stop_times
    GROUP BY trip_id
) tg ON t.trip_id = tg.trip_id
JOIN stop_times stFirst ON tg.trip_id = stFirst.trip_id AND stFirst.stop_sequence = tg.minS
JOIN stop_times stLast ON tg.trip_id = stLast.trip_id AND stLast.stop_sequence = tg.maxS
JOIN stops stFirstStop ON stFirst.stop_id = stFirstStop.stop_id
JOIN stops stLastStop ON stLast.stop_id = stLastStop.stop_id
SET t.origin = stFirstStop.stop_name,
    t.destination = stLastStop.stop_name,
    t.starts = stFirst.arrival_time,
    t.ends = stLast.arrival_time
注意:将trip_id更改为INT将提供更好的性能


此外,trips表应存储起点id和目的地id,这两个id可以稍后连接到stops表以查找名称,而不是将名称存储在所有行中

您是如何衡量其效率的?请发布您的表定义,我不知道与一个更好的解决方案(如果有)相比,它是否效率低下。我在一个大的数据集上运行这个程序,需要很多分钟。就SQL而言,您觉得它正常吗?该联接是内部联接还是外部联接?抱歉,如果这是初学者的问题。你能解释一下为什么这可能更快吗?我不能将trip_id更改为INT,因为有些id可能是真正的字符串。除了附加索引外,您能简要解释一下为什么使用这些连接比原来的4个子选择更快吗?谢谢。@dan子查询将对每一行执行,联接将在开头执行,并将保存在内存或临时表中。使用联接有很多优点,索引查找更少,随机IO更少,并且您使用的子查询(限制为1)中包含多个表,这非常昂贵。谢谢。我真的很感谢你的帮助,我还没试过。我仍然在执行我原来的update命令并对其计时。该命令已运行超过15分钟。
update trips t JOIN (
    SELECT trip_id, MIN(stop_sequence) minS, MAX(stop_sequence) maxS 
    FROM stop_times
    GROUP BY trip_id
) tg ON t.trip_id = tg.trip_id
JOIN stop_times stFirst ON tg.trip_id = stFirst.trip_id AND stFirst.stop_sequence = tg.minS
JOIN stop_times stLast ON tg.trip_id = stLast.trip_id AND stLast.stop_sequence = tg.maxS
JOIN stops stFirstStop ON stFirst.stop_id = stFirstStop.stop_id
JOIN stops stLastStop ON stLast.stop_id = stLastStop.stop_id
SET t.origin = stFirstStop.stop_name,
    t.destination = stLastStop.stop_name,
    t.starts = stFirst.arrival_time,
    t.ends = stLast.arrival_time