我有一张包含数百万行的巨大表格,用于存储从某些气象站获得的值。每行包含收集值的站点,度量标准(例如,温度,噪声级别等),日期和值本身。
这是它的结构:
metric
:int(8)date
:int(8)value
:datetime station+metric+date
:float 这些是我定义的指数:
metrica
SELECT station, MAX(date)
FROM MyTable
GROUP BY station
(对于外键)有时候,我有兴趣检索每个电台上次发送一些价值的时间。然后我使用这个查询:
public interface DetatchableItemRepositoryCustom {
void detach(Interaction clone);
}
public interface DetatchableItemRepository extends JpaRepository<Interaction, Long>,
DetatchableItemRepositoryCustom {
}
public class DetatchableItemRepositoryImpl implements DetatchableItemRepositoryCustom {
}
此查询非常慢,因为它必须读取整个表。如果我为station + date添加索引,则查询现在可以使用它并且变得非常快。但是表存储也增加了很多,对我来说索引所有日期值都没用,因为我只对最大值感兴趣。
所以我的问题是,是否可以创建索引某个范围的索引,理想情况下只跟踪最大值。
答案 0 :(得分:1)
不是我知道的。但是你有其他解决方案。
在其他数据库中,我建议使用物化视图,但MySQL不支持物化视图(SO#3991912),因此您必须自己创建和管理自己的聚合表。
如果您的源表未经常更新,CREATE TABLE last_observation AS SELECT station, MAX(date) AS date FROM observations GROUP BY station
将完成工作。只需在任何相关请求之前发布声明。
如果您的服务器有足够的资源,您可以将表格保留在MEMORY,以获得超快的响应。在这种情况下,您需要明确命名列CREATE TABLE last_observation (station VARCHAR(x), lastDate DATE) ENGINE=MEMORY AS SELECT station, MAX(date) AS lastDate FROM observations GROUP BY station
。当然,每次打开mysql时都应该定期发出这个语句。
如果您的表经常更新,您可以在源表(Full tutorial here)上使用触发器管理内容。
另一种完全不同的解决方案是使用面向列的数据库。我们几年前使用过Infobright,它有一个免费的社区版本,对你来说完全透明(只需安装它并像以前一样使用mysql)。
答案 1 :(得分:0)
INDEX(station, date)
将有效地处理 查询。或者,您可以将PRIMARY KEY
重新排列为(station, date, metric)
。
如果您还希望在该日期获得临时值,那么您将变得更加复杂groupwise-max。