2010-02-09 2 views
2

Добрый день, у меня есть вопрос, с которым я много борюсь, надеюсь, что кто-то уже нашел умное решение для этого (я использую MySQL).Выберите только самые новые записи из таблицы и сделайте это FAST, как?

У меня есть таблица вроде этого:

Table `log` 
---------- 
id 
inserted 
message 
user_id 

Моя цель состоит в том, чтобы выбрать последнюю вставленную запись для пользователя, и сделать это быстро. Вход стол огромный (около 900k записей), поэтому мой первый подход:

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 показывает Зависимые QUERY). Когда я разделил этот вопрос на две части:

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...) 

Это приемлемо для запуска. Может ли это быть достигнуто одним запросом?

ответ

1

В дополнении к использованию группы по для извлечения группы мудра максимума вы, вероятно, хотите, чтобы сделать его некоррелированный подзапрос для извлечения дополнительных полей для конкретных строк из таблицы.

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`) 

, но даже без этого ключа производительность спуска.

+0

Он работает! Большое спасибо! Это задумано в SQL-способе! – artvolk

+0

Имейте в виду, что я не эксперт (Мой) SQL. Вполне возможно, что кто-то еще представит гораздо лучшее решение (+ указывает на проблемы с этим решением). Я взял на себя смелость изменить теги в надежде «заманить» (даже) больше экспертов на эти вопросы ;-) – VolkerK

4

Как насчет

SELECT user_id, max(id) FROM `log` GROUP BY user_id 

?

Это даст вам максимальный идентификатор для каждого пользователя в таблице журналов, все в одном запросе!

+0

См. Мой ответ, чтобы ускорить это. –

+0

Но как насчет поля 'сообщение'? Вероятно, это тоже должно быть в результирующем наборе. – VolkerK

+0

Да, VolkerK прав, мне нужны другие поля (например, 'сообщение'). – artvolk

1

Если вы всегда ищете журнал для определенного пользователя, разбиение файла журнала на user_id будет ускорять работу. Если таблица разделена пользователем и индексируется по id, запрос будет выполняться очень быстро.

EDIT: см запрос Dominik в

0

Кроме того, я хотел бы убедиться, что у вас есть индекс по user_id.

EDIT: обобщенный