Выберите запись на основе последней отметки времени

Я видел несколько подобных типов вопросов, однако я не смог найти лучшего решения. Мне нужно оптимизировать этот запрос.

itemid           state_id                timestamp
======================================================
  1              1              2012-08-11 00:00:00
  1              2              2012-08-12 00:00:00
  1              3              2012-08-13 00:00:00
  2              1              2012-08-10 00:00:00
  2              2              2012-08-13 00:00:00   <=== lastest  state_id =2
  3              1              2012-08-10 00:00:00
  3              2              2012-08-13 00:00:00
  3              4              2012-08-15 00:00:00
  4              1              2012-08-10 00:00:00
  4              3              2012-08-13 00:00:00
  4              2              2012-08-16 00:00:00   <=== lastest state_id =2
  5              1              2012-08-16 00:00:00

Мне нужно выбрать itemid на основе последней отметки времени и state_id = 2.

У меня есть этот запрос http://sqlfiddle.com/, но я думаю, что он не оптимизирован для большой таблицы, Есть идеи? Спасибо!

SELECT *
FROM hops h
WHERE h.timestamp = (
SELECT MAX( h2.`timestamp` )
FROM hops h2
WHERE h.`itemid` = h2.`itemid` )
AND h.state_id = 2

3 ответа

Решение
SELECT * FROM hops a
inner join (SELECT itemid, MAX(timestamp) FROM hops group by itemid) b
ON a.itemid  = b.itemid
 where a.STATE_ID = 2

Это выполнит внутреннее объединение для подзапроса, который фактически должен выбирать только записи, связанные со значением метки времени MAX в соответствующей таблице.

Таким образом, вы будете выбирать меньше строк, которые при внутреннем объединении будут возвращать только те строки, которые вы выбрали в подзапросе, но с выводом результата, указанным с помощью SELECT *

Теперь вы получили объединение вместо использования предложения WHERE, что позволит свести к минимуму количество поисков вашей таблицы SQL вашим движком. или таблица сканирует, как вы это называете.

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

SELECT itemid, timestamp 
FROM hops t1 
WHERE state_id = 2 
AND timestamp > (
   SELECT MAX(timestamp)
   FROM hops t2 
   WHERE t1.itemid = t2.itemid 
   AND t2.state_id != 2
)
GROUP BY itemid

Я проверил код, и он работает нормально, вы можете увидеть, что он работает на http://sqlfiddle.com/

Предполагая, что вы ищете только одну возвращаемую запись, вы можете использовать что-то вроде:

SELECT *
FROM hops h
WHERE
h.state_id = 2
ORDER BY timestamp DESC limit 1
Другие вопросы по тегам