Справочная информация:
Веб-приложение для электронной коммерции, но с «участниками», которые заказывают друг у друга.Когда участник выполняет различные действия (такие как поиск), записи вставляются в таблицу «Действия».Если / когда участник отправляет заказ, запись вносится в таблицу «Заказ».Цель состоит в том, чтобы найти случаи, когда участник выполнял действие, но НЕ размещал заказ в течение некоторого периода времени (скажем, часа) после времени действия.
ПРИМЕЧАНИЕ. Код, который создает записи заказане может быть измененоЕсли бы это было возможно, я мог бы просто «запомнить» действия и включить эту информацию в записи заказа.Затем найти случаи, когда член выполнил действие, но не разместил заказ, было бы просто: просто найдите значение NULL (или другое значение по умолчанию) в этом столбце таблицы заказов.Опять же, увы, в моей ситуации это невозможно ...
Таблицы:
Order
(id, ts / * timestamp * /, send_member_id, receive_member_id,…) Member
(идентификатор, имя,…) Activity_Type
(идентификатор, имя,…) Activity_Log
(идентификатор, ts, member_id, type_id,extra_info)
Индексы:
All appropriate indexes are in place. Specifically, an index on order.ts does exist.
Я пробовал эти три запроса:
ПОДХОД 1
SELECT …
FROM activity_log,
Member
WHERE activity_log.member_id = member.id
AND activity_log.type_id = 1 /* Search */
AND activity_log.ts > [start time]
AND activity_log.ts < [end time]
AND NOT EXISTS (SELECT ‘x’
FROM order
WHERE order.ts >= activity_log.ts
AND order.ts <= activity_log.ts + 3600
AND order.sending_member_id = activity_log.member_id)
ORDER BY activity_log.member_id, activity_log.ts desc
ПОДХОД 2
SELECT …
FROM activity_log, member
WHERE activity_log.member_id = member.id
AND activity_log.type_id = 1 /* Search */
AND activity_log.ts > [start time]
AND activity_log.ts < [end time]
AND activity_log.member_id NOT IN (SELECT order.sending_member_id
FROM order
WHERE order.ts >= activity_log.ts
AND order.ts <= activity_log.ts + 3600)
ORDER BY activity_log.member_id, activity_log.ts desc
APPROACH 3
SELECT …
FROM activity_log
JOIN member ON activity_log.member_id = member.id
LEFT JOIN order ON order.ts >= activity_log.ts
AND order.ts <= activity_log.ts + 3600
AND activity_log.member_id = order.sending_member_id
WHERE activity_log.type_id = 1 /* Search */
AND activity_log.ts > [start time]
AND activity_log.ts < [end time]
AND order.sending_member_id IS NULL
ORDER BY activity_log.member_id, activity_log.ts desc
Даже при подходе 3 запрос выполняется в течение 20-30 секунд и не использует индекс для order.ts.