Выберите только самые новые записи из таблицы и сделайте это БЫСТРО, как?
-
19-09-2019 - |
Вопрос
Добрый день, у меня есть вопрос, с которым я много разбираюсь, надеюсь, кто-нибудь уже нашел умное решение этой проблемы (я использую MySQL).
У меня есть такая таблица:
Table `log`
----------
id
inserted
message
user_id
Моя цель — выбрать последнюю вставленную запись для пользователя и сделать это быстро.Таблица журналов огромно (около 900 тыс. Записок), поэтому мой первый подход был:
SELECT * FROM `log`
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id`
WHERE `id` IN
(
SELECT MAX(`id`) FROM `log` GROUP BY `user_id`
)
Но кажется, что он рассчитывает подзапрос для каждой строки (EXPLAIN показывает ЗАВИСИМЫЙ ЗАПРОС).Когда я разделил этот запрос на два:
SELECT MAX(`id`) FROM `log` GROUP BY `user_id`
и
SELECT * FROM `log`
LEFT JOIN `users` ON `users`.`id` = `log`.`user_id`
WHERE `id` IN (....ids from first query...)
Допустимо бегать.Можно ли этого добиться одним запросом?
Решение
В дополнение к использованию group by для получения максимального значения для группы вы, вероятно, захотите сделать его некоррелированным подзапросом для получения дополнительных полей для определенных строк из таблицы.
SELECT
la.user_id,la.message
FROM
`log` as la
INNER JOIN
(
SELECT
user_id, MAX(id) AS maxid
FROM
`log`
GROUP BY
user_id
) as lb
ON
la.id = lb.maxid
Это работает лучше всего/быстрее всего, если у вас есть индекс
KEY `foo` (`user_id`,`id`)
но даже без этого ключа производительность падает.
Другие советы
Как насчет
SELECT user_id, max(id) FROM `log` GROUP BY user_id
?
Это даст вам максимальный идентификатор для каждого пользователя в таблице журнала, и все это в одном запросе!
Если вы всегда ищете журнал для конкретного пользователя, разделение файла журнала по user_id значительно ускорит работу.Если таблица разделена по пользователям и проиндексирована по идентификатору, запрос будет выполняться очень быстро.
РЕДАКТИРОВАТЬ:см. запрос Доминика
Кроме того, я хотел бы убедиться, что у вас есть индекс user_id.
РЕДАКТИРОВАТЬ:обобщенный