【问题标题】:MySQL index for only maximum and minimum valuesMySQL索引仅用于最大值和最小值
【发布时间】:2017-12-10 09:35:14
【问题描述】:

我有一个包含数百万行的巨大表,其中存储从某些气象站获得的值。每行都包含收集值的站点、指标(例如温度、湿度、噪音水平等)、日期和值本身。

这是它的结构:

  • station: int(8)
  • metric: int(8)
  • date: 日期时间
  • value: 浮动

这些是我定义的索引:

  • 主键:station+metric+date
  • KEY:metrica(外键)

有时,我有兴趣检索每个站点上一次发送某些值的时间。然后我使用这个查询:

 SELECT station, MAX(date)
 FROM MyTable
 GROUP BY station

这个查询很慢,因为它必须读取整个表。如果我为站+日期添加索引,现在查询可以使用它并且变得非常快。但是表存储也增加了很多,对我来说索引所有日期值没有用,因为我只对最大值感兴趣。

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

【问题讨论】:

  • 您最好将该信息存储在另一个表中——比如Stations 表——并在每次插入一行时使用触发器更新信息。
  • 可以把PK改成station+date+metric吗?从功能上讲,它是一样的,但实际上它(几乎)与添加额外索引的情况一样快。
  • @deroby 我试过了,确实查询会立即运行。但是另一个频繁查询,例如“列出一个站点的一周温度值”现在执行速度较慢(不是那么多,慢了大约 25%)。鉴于最后一个在我的应用程序中更为频繁,我将保留我以前的主键。谢谢!

标签: mysql indexing max query-optimization


【解决方案1】:
INDEX(station, date)

将有效地处理那个查询。或者,您可以将 PRIMARY KEY 重新排列为 (station, date, metric)

如果您还想要该日期的温度,那么您将进入更复杂的groupwise-max

【讨论】:

    【解决方案2】:

    我不知道。但是您有其他解决方案。

    在其他数据库中,我建议使用物化视图,但 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)。

    【讨论】:

      猜你喜欢
      • 2013-01-11
      • 2014-11-05
      • 2020-09-19
      • 2021-08-17
      • 1970-01-01
      • 2013-03-04
      • 2014-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多