MySQL索引仅用于最大值和最小值

时间:2017-07-06 11:40:28

标签: mysql indexing max query-optimization

我有一张包含数百万行的巨大表格,用于存储从某些气象站获得的值。每行包含收集值的站点,度量标准(例如,温度,噪声级别等),日期和值本身。

这是它的结构:

  • metric:int(8)
  • date:int(8)
  • value:datetime
  • station+metric+date:float

这些是我定义的指数:

  • PRIMARY KEY:metrica
  • KEY: 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添加索引,则查询现在可以使用它并且变得非常快。但是表存储也增加了很多,对我来说索引所有日期值都没用,因为我只对最大值感兴趣。

所以我的问题是,是否可以创建索引某个范围的索引,理想情况下只跟踪最大值。

2 个答案:

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