我有一个表,收集不同城市的温度样本,这些样本通过城市 ID 进行区分。每个样本都与时间戳一起保存。
+----+---------+-------------+---------------------+
| id | city_id | temperature | fetched |
+----+---------+-------------+---------------------+
| 1 | 1 | 10 | 2016-01-28 00:50:27 |
| 2 | 1 | 12 | 2016-01-27 23:51:45 |
| 3 | 2 | 22 | 2016-01-27 23:52:05 |
| 4 | 2 | 25 | 2016-01-28 00:52:25 |
+----+---------+-------------+---------------------+
如果我想获得所有城市的最新气温,我可以使用自连接[1]:
SELECT s.*
FROM sample s
INNER JOIN (
SELECT city_id, MAX(fetched) maxFetched
FROM sample
GROUP BY city_id
) j
ON s.city_id = j.city_id AND s.fetched = j.maxFetched;
+----+---------+-------------+---------------------+
| id | city_id | temperature | fetched |
+----+---------+-------------+---------------------+
| 1 | 1 | 10 | 2016-01-28 00:50:27 |
| 4 | 2 | 25 | 2016-01-28 00:52:25 |
+----+---------+-------------+---------------------+
现在,我想知道当我的表增长时的性能。想象一下,我每小时在每个城市收集 1 个样本,例如10个城市,一年后,该表将包含10*24*365=87600个样本。 MAX 函数的运行时间会随着输入大小线性增加吗? IE。拥有另一张 table 会是更好的做法吗? last_sample,它保存指向最新样本的指针,以便查找每个城市的最新温度只需要恒定的时间(可能会在添加新样本时自动更新)?当查询在 View 中抽象时,同样的问题也适用。
SELECT * FROM last_sample;
+------+---------+-----------+
| id | city_id | sample_id |
+------+---------+-----------+
| 1 | 1 | 1 |
| 2 | 2 | 4 |
+------+---------+-----------+
谢谢!
最佳答案
这是“groupwise max”问题的一个例子。你的代码“还不错”。有例子in here更快的方法来做到这一点并扩大规模。它还讨论了当存在具有相同 Max 的多行时,如果您想要/不想要多行该怎么办。
对于您的代码,请确保具有以下复合索引:
INDEX(city_id, fetched)
您的子查询将仅使用索引。 (EXPLAIN SELECT ...
将显示“使用索引”。)并且,我认为,通过索引跳跃式查找“city,max(fetched)”对非常有效。
然后您的 JOIN
将使用相同的索引返回到表中。
更好的是摆脱 id
(它真的有任何用途吗),因为 (city_id, fetched)
是“唯一的”(是的?)并且,因此,可能是主键
。在这种情况下,就不需要我建议的 INDEX
了。并且所有辅助探针都将非常有效(因为使用 PK)。
底线:
- 扔
id
- 更改为“主键(city_id,已获取)”
- (您不会在我的博客中找到更好的内容。)
- 它将线性增长(输出也将线性增长)
但是...如果您决定将其限制为在 BETWEEN ... AND ... 之间获取
,那么所有的赌注都会被取消。 (我需要重新考虑事情。)
关于mysql - 数据库 : performance of dynamic vs. 表中最新样本的静态查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35050687/