我有一个Raspberry Pi,我一直用它来记录从一堆1-Wire传感器收集的家庭温度数据。数据已经在几年内被收集到MySQL数据库中。我使用Raspbian发行版和默认的MySQL配置。我现在有一个包含超过一百万条记录的表格,我的Pi正在非常缓慢地运行查询。
以下是TemperatureRecords表的说明:
+--------------+----------+------+-----+---------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------+------+-----+---------------------+-------+
| timeRecorded | datetime | NO | PRI | 0000-00-00 00:00:00 | |
| sensorName | char(3) | NO | PRI | | |
| tempValue | float | YES | | NULL | |
+--------------+----------+------+-----+---------------------+-------+
我记录了日期和时间,3个字符的传感器名称和温度值。 我想运行两个查询,一个用于选择某个传感器的当前(最近)温度,另一个用于选择当天的最高温度。
当前温度示例:
SELECT ROUND(tempValue, 1) as tempValue
FROM TemperatureRecords
WHERE DATE(timeRecorded) = '2015-01-20' AND HOUR(timeRecorded) = '20' AND sensorName = 'abc'
ORDER BY timeRecorded DESC LIMIT 1;
最高温度示例:
SELECT MAX(tempValue)
FROM TemperatureRecords
WHERE DATE(timeRecorded) = '2015-01-20' AND sensorName = 'abc';
不幸的是,这可能需要10-20秒才能完成,这太慢了,特别是当我想从多个传感器检索数据以便立即在网页上显示时。
我已尝试在表中添加其他索引,但这没有任何改进,我不确定我是否完全理解索引。我也尝试将MySQL配置用于/usr/share/doc/mysql-server-5.5/examples/my-small.cnf中的小型系统,我被告知可能会提高性能但无济于事。
我对MySQL的了解有点基础。我现在对Raspberry Pi的期望很高,我的数据已经变得如此之大,或者我有什么办法可以改善我的设置?
答案 0 :(得分:3)
罪魁祸首是WHERE DATE(timeRecorded) = '2015-01-20'
- 它为所有行计算DATE()
(无论它们是否匹配)并且不允许使用索引。
尝试:WHERE timeRecorded >= '2015-01-20 00:00:00' and timeRecorded < '2015-01-21 00:00:00'
有关详情,请参阅this SO question!
答案 1 :(得分:1)
调用DATE()
之类的方法会立即让您遇到麻烦。这些不能被编入索引,如果没有索引,你就会死在水中。
如果您经常拨打这些电话,请创建一个DATE
列,其中包含您正在搜索的数据。您可能还需要一列来捕获您正在提取的小时信息。
数据库规范化原则适用,直到您遇到这样的情况,其中理想形式的速度慢得令人无法接受。在这种情况下,您需要仔细去标准化以解决这些问题。保持这样的数据同步可能很棘手,因此每当对主日期进行更改时,请务必使所有这些派生列保持最新。
如果您可以将其缩小到一段时间,您可能有机会使用DATETIME
,例如:
WHERE timeRecorded BETWEEN '2015-01-20 20:00:00' AND '2015-01-20 20:59:99'
如果可行,您的现有索引将适用。
答案 2 :(得分:1)
我认为你所追求的是在Raspberry Pi上可以实现的,你只需要改变重处理查询的处理方式。
如果是历史数据,请每天处理数据并保存到另一个(更小,更快)的表格中,以便网页快速引用。
小时平均值也只在每小时运行一次,保存在单独的表格中。
将当前温度放在缓冲表和记录中,但只允许网页访问缓冲表。
它可能不那么准确,但希望差异很小,但你应该看到一个大的速度提升