Как мне ускорить мой запрос MySQL, который получает среднее значение самой последней транзакции для каждого пользователя?

#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 есть составной индекс.