MySQL команда обновления с несколькими подобными суб-выборами

0

Я написал следующую команду UPDATE, но там избыточность в подвыборках. Я не являюсь экспертом в области 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 и 2 миллиона stop_times. Может быть, в среднем 20? упоры за одну поездку (просто гадание).

create table stop_times (
  trip_id varchar(255),
  arrival_time time,
  stop_id varchar(255),
  stop_sequence int unsigned,
) type=MyISAM;

alter table stop_times add index stop_id (stop_id(5));
alter table stop_times add index trip_id (trip_id(5));

create table stops (
  stop_id varchar(255),
  stop_name varchar(255),
  stop_lat float,
  stop_lon float,
  primary key (stop_id)
) type=MyISAM;

create table trips (
  route_id varchar(255),
  trip_id varchar(255), /* primary key is here */
  /* denormalized fields */
  origin varchar(255),
  destination varchar(255),
  starts time,
  ends time,
  primary key(trip_id)
) type=MyISAM;
alter table trips add index route_id (route_id(5));
  • 1
    как ты измерил что это неэффективно?
  • 1
    Пожалуйста, опубликуйте свои определения таблиц, а также количество остановок, которые будет иметь каждая поездка.
Показать ещё 1 комментарий
Теги:

1 ответ

1
Лучший ответ

Сначала добавьте индекс stop_times, чтобы включить столбцы trip_id и stop_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 даст вам лучшую производительность

Кроме того, в таблице маршрутов должны храниться элементы origin_id и destination_id, которые впоследствии могут быть соединены с таблицей стопов, чтобы найти имя, вместо того, чтобы хранить имя во всех строках

  • 0
    Это соединение является внутренним или левым внешним соединением? Извините, если это вопрос новичка. Не могли бы вы также немного объяснить, почему это может быть быстрее?
  • 0
    @dan внутреннее соединение
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню