У меня есть база данных MySQL с таблицами, представляющими возможные маршруты автобуса.Тремя соответствующими таблицами являются таблица carpool (количество элементов ~ 2 миллиона), таблица carpool_stop (число элементов ~ 11 миллионов) и таблица поездок (количество элементов ~ 300K).Поездки представляют собой запрос на перемещение из местоположения A в местоположение B. Автомобильные бассейны представляют собой возможный маршрут, по которому автомобиль может совершить несколько поездок одновременно, подбирая пользователей в нескольких местах и отбрасывая их в нескольких местах.Вот примеры: carpool:
+------------+-----------+
| carpool_id | completed |
+------------+-----------+
| 1 | 0 |
| 2 | 0 |
| 3 | 1 |
+------------+-----------+
carpool_stop:
+------------+---------+---------+
| carpool_id | trip_id | type |
+------------+---------+---------+
| 1 | 1 | pickup |
| 1 | 2 | pickup |
| 1 | 2 | dropoff |
| 1 | 1 | dropoff |
| 2 | 2 | pickup |
| 2 | 3 | pickup |
| 2 | 3 | dropoff |
| 2 | 2 | dropoff |
| 3 | 3 | pickup |
| 3 | 4 | pickup |
| 3 | 4 | dropoff |
| 3 | 3 | dropoff |
+------------+---------+---------+
trip:
+---------+------------+---------------+--------------+
| trip_id | carpool_id | status | pickup_date |
+---------+------------+---------------+--------------+
| 1 | NULL | 'INITIAL' | '2019-04-01' |
| 2 | NULL | 'INITIAL' | '2019-04-02' |
| 3 | 3 | 'IN_PROGRESS' | '2019-04-03' |
| 4 | 3 | 'INITIAL' | '2019-04-03' |
+---------+------------+---------------+--------------+
Существует указатель на trip.pickup_date.Цель состоит в том, чтобы получить все carpools, которые удовлетворяют этим условиям:
at least one trip has a pickup_date later than a specified date
AND
(the carpool is completed OR
(all trips have status in ('INITIAL', 'WAITING') AND have a NULL carpool_id))
В приведенном выше примере, если заданный параметр pickup_date был '2019-04-02', это были бы carpools 1 и 3. Carpool 2 будетне возвращается, так как поездка 3 уже является частью автобазы и имеет значение IN_PROGRESS.
У меня есть рабочий запрос, но теперь он занимает 10 минут для указанной даты pickup_date, которая была только днем в прошлом, потому чтоколичества строк в таблице carpool_stop.
SELECT carpool.*
FROM (
SELECT carpool_stop.carpool_id
FROM trip
JOIN carpool_stop ON carpool_stop.trip_id = trip.trip_id
JOIN carpool ON carpool.carpool_id = carpool_stop.carpool_id
WHERE trip.pickup_date >= '2019-04-02'
GROUP BY carpool.carpool_id
) AS inner_query
JOIN carpool ON carpool.carpool_id = inner_query.carpool_id
JOIN carpool_stop ON carpool_stop.carpool_id = carpool.carpool_id
JOIN trip ON trip.trip_id = carpool_stop.trip_id
GROUP BY carpool.carpool_id
HAVING (sum(CASE WHEN (trip.status NOT IN ('INITIAL', 'WAITING') OR trip.carpool_id IS NOT NULL)
THEN 1
ELSE 0
END) = 0
OR carpool.completed = 1)
Я надеюсь, что способ написать этот запрос будет намного быстрее, например, порядка минуты или меньше.