Mysql 数据库:表中最新样本的动态与静态查找性能

Mysql 数据库:表中最新样本的动态与静态查找性能,mysql,database-design,mariadb,Mysql,Database Design,Mariadb,我有一个表格,收集不同城市的温度样本,通过城市id进行区分。每个样本都与时间戳一起保存 +----+---------+-------------+---------------------+ | id | city_id | temperature | fetched | +----+---------+-------------+---------------------+ | 1 | 1 | 10 | 2016-01-28 00:50

我有一个表格,收集不同城市的温度样本,通过城市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 |
+----+---------+-------------+---------------------+
现在,我想知道当我的桌子变大时的性能。假设我每小时收集一个样本,例如10个城市,一年后,该表将包含10*24*365=87600个样本。MAX函数的运行时间是否会随着输入大小线性增加?例如,最好使用另一个表格,例如last_sample,该表格保存指向最新样本的指针,以便每个城市的最新温度查找只需要恒定的时间(可能在添加新样本时自动更新)?当查询在视图中抽象时,同样的问题也适用

SELECT * FROM last_sample;
+------+---------+-----------+
| id   | city_id | sample_id |
+------+---------+-----------+
|    1 |       1 |         1 |
|    2 |       2 |         4 |
+------+---------+-----------+
谢谢

[1]

这是“groupwise max”问题的一个例子。你的代码“还不错”。这里有一些快速实现和扩展的例子。它还讨论了当有多行具有相同的最大值时,如果您不想要多行,该怎么办

对于您的代码,请确保具有以下复合索引:

INDEX(city_id, fetched)
子查询将仅使用索引。(EXPLAIN SELECT…将显示“使用索引”。)并且,我认为,通过索引快速查找“city,max(fetched)”对非常有效

然后您的
JOIN
将使用相同的索引返回到表中

更好的办法是去掉
id
(它真的有任何用途吗),因为
(city\u id,fetched)
是“唯一的”(是吗?),因此可能是
主键。在这种情况下,不需要我建议的
索引。所有的二级探针都会非常有效(因为使用了PK)

底线:

  • 投掷
    id
  • 更改为“主键(城市标识,已提取)
  • (你在我的博客里找不到比这更好的了。)
  • 它将线性增长(输出也将线性增长)

但是。。。如果您决定将其限制为在以下时间之间获取的
。。。而且…
,所有赌注都输掉了。(我需要重新考虑一下。)

谢谢你,瑞克!对于这个例子,我可以删除
id
(city\u id,fetched)
在这里是唯一的。但如果我链接到另一个表中的样本(例如,
other.sample\u id->sample.id
作为外键),这会是一个好主意吗?当我不知道时间戳是什么样子时,我该如何查询表呢?