Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 优化SQL查询-传感器读数_Mysql_Sql_Time Series_Aggregate Functions - Fatal编程技术网

Mysql 优化SQL查询-传感器读数

Mysql 优化SQL查询-传感器读数,mysql,sql,time-series,aggregate-functions,Mysql,Sql,Time Series,Aggregate Functions,我有两张桌子 Sensorlist id (int, PK) alias (varchar) Readings sensorid (int) value (decimal) date (datetime) id (bigint, PK) 读数表具有id、传感器id和日期索引。这是在MYSQL中,在raspberry pi上运行 我想得到一个列表,显示列表中的每个传感器,以及它们最近的读数和过去24小时内的最小和最大读数 我有以下两个查询,我将它们组合成一个数组并显示出来。我不太清楚如何将这两

我有两张桌子

Sensorlist
id (int, PK)
alias (varchar)

Readings
sensorid (int)
value (decimal)
date (datetime)
id (bigint, PK)
读数表具有id、传感器id和日期索引。这是在MYSQL中,在raspberry pi上运行

我想得到一个列表,显示列表中的每个传感器,以及它们最近的读数和过去24小时内的最小和最大读数

我有以下两个查询,我将它们组合成一个数组并显示出来。我不太清楚如何将这两个作为一个查询来执行。第一个查询非常慢。我怎样才能使它更有效率

获取最新读数需要27秒:

select distinct s.alias, s.id, a.maxdate, r.value from sensorlist s
inner join
(
SELECT MAX(date) maxDate, sensorid FROM readings GROUP BY sensorid
) a on a.sensorid = s.id
inner join readings r on r.sensorid = s.id and r.date = a.maxdate 
ORDER BY s.alias
查询2获取过去24小时内的最小/最大值,这只需要0.3秒:

select distinct s.alias, s.id, max(value) as maxval, min(value) as minval from sensorlist s
 inner join readings r on r.sensorid = s.id where r.date > DATE_SUB(NOW(), INTERVAL 24 HOUR) group by r.sensorid
我假设这是我连接子查询的方式。。但是我无法解决如何不使用子查询,或者如何在一个查询中完成整个任务(如果这是一个更有效的路由?)

谢谢你的建议, 查利

编辑-完成的查询(如下答案所示,但MYSQL不喜欢“minvalue”这个词,根据答案添加索引)


非常感谢

此查询获取最近24小时内每个传感器的最大和最小读数。注意没有任何
不同的
指令;
groupby
会为您做这件事

          SELECT sensorid, MAX(value) AS maxvalue, MIN(value) AS minvalue
            FROM readings
           WHERE date >= NOW() - INTERVAL 24 HOUR
           GROUP BY sensorid
如果您在
读数
表上创建以下复合索引,则此查询很可能会大大提高性能:
(日期、传感器ID、值)
。这叫做覆盖索引,你可以在你最喜欢的搜索引擎上找到它。它允许MySQL使用随机访问精确地跳转到索引中的正确位置,然后按顺序扫描该索引以查找所需的信息。通过该索引可以满足整个查询

现在,让我们添加最新的测量要求。查找每个传感器的最新测量值的最简单方法是使用此子查询。我假设你的PK,
reads.id
,是一个自动递增字段

SELECT MAX(id) id, sensorid  FROM sensors GROUP BY sensorid
该查询将在
读数
表中提供
id
值的列表。这些是每个不同传感器最近读数的
id
值。要优化它,您可以在
(sensorid,id)
上创建另一个覆盖索引

现在,我们可以将该子查询连接到查询的其余部分,并使用这些ID查找最新的值。请注意,我们最终得到两个不同的子查询。这是必要的,因为我们需要两种不同的聚合,根据不同的标准聚合。我们还将连接传感器别名以进行显示

SELECT sensorlist.id, sensorlist.alias, a.maxvalue, a.minvalue, b.value AS lastvalue
  FROM (
          SELECT sensorid, MAX(value) AS maxvalue, MIN(value) AS minvalue
            FROM readings
           WHERE date >= NOW() - INTERVAL 24 HOUR
           GROUP BY sensorid
       ) AS a
  JOIN (
          SELECT value, sensorid
            FROM sensors
            JOIN (
                   SELECT MAX(id) id FROM sensors GROUP BY sensorid
                 ) AS m ON sensors.id = m.id
       ) AS b ON a.sensorid = b.sensorid
  JOIN sensorlist ON sensorlist.id = a.sensorid
使其性能良好的诀窍是通过使用适当的索引来优化命中读数表的两个子查询

最后,您可以测试这个查询,它结合了两个聚合器查询,看看它是否更快

SELECT sensorlist.id, sensorlist.alias, a.maxvalue, a.minvalue, b.value AS lastvalue
  FROM (
          SELECT sensorid, MAX(value) AS maxvalue, MIN(value) AS minvalue,
                 MAX(id) AS maxid
            FROM readings
           WHERE date >= NOW() - INTERVAL 24 HOUR
           GROUP BY sensorid
       ) AS a
  JOIN readings AS b on b.id = a.maxid
  JOIN sensorlist ON sensorlist.id = a.sensorid

相当快的速度是一个轻描淡写的说法,因为它现在运行在0.134秒!谢谢
SELECT sensorlist.id, sensorlist.alias, a.maxvalue, a.minvalue, b.value AS lastvalue
  FROM (
          SELECT sensorid, MAX(value) AS maxvalue, MIN(value) AS minvalue,
                 MAX(id) AS maxid
            FROM readings
           WHERE date >= NOW() - INTERVAL 24 HOUR
           GROUP BY sensorid
       ) AS a
  JOIN readings AS b on b.id = a.maxid
  JOIN sensorlist ON sensorlist.id = a.sensorid