从MySQL / MariaDB表中最新插入的行中选择行

时间:2018-07-02 00:52:47

标签: mysql mariadb

我将传感器数据记录到MariaDB表中……基本上,三列:

  • ts-阅读时间
  • srcID-TINYINT UNSIGNED代表报告数据的传感器的ID
  • value-SMALLINT UNSIGNED-16位值

共有三种主要用例:

  1. 获取传感器读数时插入表中的数据...大约4 /分钟/传感器。一般来说,记录将在读取传感器后立即插入...如果由于某些原因导致插入失败超过几分钟,则根本不会插入记录。

  2. 获取每个信号源的最新传感器读数,最多返回15分钟。这大约每15秒发生一次,并且需要非常快。

  3. 从过去的小时/天/周/月/月等中选择值作为长期图表。这将是相对少见的情况,并且可以忍受缓慢。

我的大问题...

  1. 是否存在一种MySQL / MariaDB表类型,该表类型按插入时间的时间顺序以物理方式存储行? (也许存档?)

  2. 是否可以告诉查询优化器“执行{this-query},但不是从头开始进行全表(或分区)扫描,而是扫描表中的500条最新行” ? (理论:如果按插入顺序存储行,则最新读取的字面可能不是最后插入的内容,但是几乎可以肯定是最后插入的几百行之中)。

    < / li>

我可以发誓我记得读过一篇关于MySQL或MariaDB的存储引擎的文章,该存储引擎针对“日志类型”记录进行了优化,并且大致类似于此...但是现在我已经看,我什么都找不到。

我知道我可以按“ ts”上的范围对表进行分区(实际上,将按“ ts”上的范围进行分区),但是如果我每周或每月只用一个分区就可以了。 ,而不必每天管理一个分区(对于在蓝色月亮中执行一次的查询很慢是一回事……对于每隔几百毫秒才执行一次的查询则完全是另一回事)。

1 个答案:

答案 0 :(得分:1)

多少个传感器?为了“进行数学运算”,我假设为100。如果有一百万个传感器,则存在严重的缩放问题。 (无论如何,257会炸毁TINYINT。)

4 / min /传感器* 100个传感器=每秒插入7行-INSERT一侧几乎没有问题。

使用InnoDB。让我们估计40个字节/行,包括尚未指定的索引。总计每年大约8GB。没问题,我想。

您将保留数据多长时间?这无关紧要,因为我将设计其余部分以进行适当缩放。

听起来您想读取最近15分钟内的所有传感器?那将是6K行(用于100个传感器)? 240KB。我们需要担心的是,不要分散太多行以至于无法在15分钟内保持高速缓存。 没有问题。

PRIMARY KEY只有(?)两种选择:

(ts, srcID)
(srcID, ts)

由于群集的原因,value就在那里。 (了解InnoDB中数据与PK的“聚类”。)

我告诉人们“在指定查询之前您不能设计模式”。所以这里去...

SELECT * FROM t WHERE ts >= NOW() - INTERVAL 15 MINUTE;

该{em>乞求 PRIMARY KEY(ts, ...),以便查询扫描240KB数据-非常快,非常有效,没有浪费。 SELECT仅需一秒钟的时间。因此,CPU大部分时间都会打nor。

对于较旧的图形,查询可以“足够快”。 “最后一小时”仅会出现与15分钟查询一样慢的时间。对于其他用户,我建议使用“摘要”表使日查询几乎与小时查询一样快,从而使CPU获得更多的美梦。

摘要表将具有

hr -- timestamp truncated to the hour
srcID
avg_value -- the AVG() over the hour
min_value -- if you want it
max_value -- if you want it
num_readings -- COUNT(*) if you want it
PRIMARY KEY(hr, srcID)

仅在每小时结束后,您将添加一组新的行。每日/每周/等图将从摘要表而非主要(“事实”)表中获取。这要小得多,因此要快得多。

或者,您可以在汇总后将数据从主表中扔掉!这样可以将磁盘空间从每年8GB减少到每年少于1GB。

摘要表的更多信息:http://mysql.rjweb.org/doc.php/summarytables

您的“大”问题:

Q1:没有数据类型或引擎; InnoDB的PRIMARY KEY控制顺序。

如果您选择在一段时间后删除数据,PARTITION BY RANGE (TO_DAYS(ts))将导致非常快的DROP PARTITIONMore。目标是不超过50个分区-如果分区太多,效率低下。如果您将数据保留5年,则建议您每月进行分区。

Q2:同样,InnoDB的PK以及“ buffer_pool”是“缓存”,都说“最新”行将坐在RAM中等待获取。 (有例外,例如在重新引导后或可能进行了一些重大维护之后。)即使高速缓存是“冷的”,“集群”也表示将执行从磁盘读取的最少次数。 240K = 15 * 16KB块-在旋转驱动器上可能为150ms;在SSD上甚至更快。 “摘要”表会将其缩小10倍(或其他数值)。

您可能已经阅读了一篇 old 文章,内容关于MyISAM最适合记录日志。那是老妇人的故事。 InnoDB有所改进; MyISAM停滞不前,已被弃用。此外,与MyISAM相比,InnoDB中PK的群集可能使您的主要SELECTs运行速度更快