我见过一些类似的问题,但是,我找不到最佳解决方案。我需要优化这个查询。
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
答案 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