根据最新时间戳选择记录

时间:2014-05-09 19:46:26

标签: mysql

我见过一些类似的问题,但是,我找不到最佳解决方案。我需要优化这个查询。

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

我需要根据最新的时间戳和state_id = 2选择itemid。

我有这个查询 http://sqlfiddle.com/#!2/a3d41/1/0  但我觉得它没有针对大桌子,任何想法进行优化?谢谢!

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 个答案:

答案 0 :(得分:1)

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引擎在你的表上查找的次数。或者表扫描你所称的任何内容。

答案 1 :(得分:0)

我认为你需要制定一个基准来看看什么是最优化的解决方案。

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

我测试了代码及其工作正常,您可以看到它在sqlfiddle

上运行

答案 2 :(得分:-1)

假设您只查找一条​​要返回的记录,您可以使用以下内容:

SELECT *
FROM hops h
WHERE
h.state_id = 2
ORDER BY timestamp DESC limit 1