#mysql #sql #query-optimization
#mysql #sql #оптимизация запроса
Вопрос:
Я почти уверен, что моя реализация для этого решения наименее эффективна (для завершения требуется 2 секунды при запуске всего 30 000 записей). Есть ли более быстрый способ?
Мой запрос MySQL, за которым следует объяснение ниже:
SELECT DATE(m.date) AS day,
AVG(t.amount) AS amount
FROM transactions s
LEFT JOIN users m
ON m.id = s.user_id
WHERE
#only consider the most recent transaction for each user
s.id = (
SELECT id
FROM transactions s2
WHERE s2.user_id = s.user_id
AND s2.created_date = (
SELECT MAX(created_date)
FROM transactions s3
WHERE s3.user_id = s.user_id
)
)
GROUP BY day
ORDER BY day;
В основном это говорит «показывать среднюю сумму транзакции в день, учитывая только самую последнюю транзакцию каждого пользователя».
Я уже создал индекс в created_date.
Я не хочу просто выбирать МАКСИМАЛЬНОЕ (transaction.id ) для транзакций, связанных с пользователем, потому что нет гарантии, что новые записи транзакций, добавленные в таблицу, всегда относятся к более новым транзакциям реального мира.
Ответ №1:
Три выборки выглядят как слишком много.
SELECT t.date, avg(t.amount)
FROM transactions t
JOIN
(SELECT user_id, max(created_date) AS max_date
FROM transactions GROUP BY user_id) AS t2
ON t.user_id=t2.user_id and t.created_date=max_date
GROUP BY t.date
ORDER BY t.date;
Обратите внимание, что сюда входят все транзакции данного пользователя за самый последний день, когда у него были какие-либо транзакции. Похоже, что метки времени нет.
Убедитесь, что на user_id, created_date
есть составной индекс.