如何在低规格系统上提高lrge表上的MySQL性能?
我有一个树莓Pi,我一直用它记录从一堆单线传感器收集的家庭温度数据。几年来,所有数据都被收集到MySQL数据库中。我使用Raspbian发行版和默认的MySQL配置。我现在有一个超过一百万条记录的表,我的Pi运行查询的速度非常慢 以下是温度记录表的说明:如何在低规格系统上提高lrge表上的MySQL性能?,mysql,sql,performance,raspberry-pi,raspbian,Mysql,Sql,Performance,Raspberry Pi,Raspbian,我有一个树莓Pi,我一直用它记录从一堆单线传感器收集的家庭温度数据。几年来,所有数据都被收集到MySQL数据库中。我使用Raspbian发行版和默认的MySQL配置。我现在有一个超过一百万条记录的表,我的Pi运行查询的速度非常慢 以下是温度记录表的说明: +--------------+----------+------+-----+---------------------+-------+ | Field | Type | Null | Key | Default
+--------------+----------+------+-----+---------------------+-------+
| 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';
最高温度示例:
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秒才能完成,这太慢了,尤其是当我想从多个传感器中检索数据以同时显示在网页上时
我曾尝试向表中添加其他索引,但这并没有带来任何改进,而且我也不确定我是否完全理解索引。我还尝试在/usr/share/doc/MySQL-server-5.5/examples/my-small.cnf中为小型系统使用MySQL配置,有人告诉我这可能会提高性能,但没有效果
我对MySQL的了解有些基础。现在我的数据变得如此之大,我是否对Raspberry Pi抱有很大期望,或者我可以做些什么来改进我的设置?调用像
DATE()
这样的方法会立即给您带来麻烦。这些不能被索引,没有索引你就死在水里了
如果您经常调用这些函数,请创建一个DATE
列,该列正好包含您正在搜索的数据。您可能还需要一个列来捕获正在提取的小时信息
数据库规范化原则一直适用,直到您遇到这样的情况,理想的表单速度慢得令人无法接受。在这种情况下,您需要仔细地去规范化以解决这些问题。保持这样的数据同步可能会很棘手,因此,无论何时更改主日期,都要确保所有这些派生列都是最新的
您可能有机会在此处使用DATETIME
,如果您可以将其缩小到一个时间范围,例如:
WHERE timeRecorded BETWEEN '2015-01-20 20:00:00' AND '2015-01-20 20:59:99'
如果这样做有效,您现有的索引将适用。罪魁祸首是
WHERE DATE(timeRecorded)='2015-01-20'
-它计算所有行的DATE()
,并禁止使用索引
尝试:WHERE timeRecorded>='2015-01-20 00:00:00'和timeRecorded<'2015-01-21 00:00:00'
详情请参阅 我认为您所追求的是可以在Raspberry Pi上实现的,您只需要改变处理繁重查询的方式 如果是历史数据,请每天处理数据并将其保存到另一个(更小、更快)表中,以便网页快速引用 每小时平均值也仅每小时运行一次,保存到单独的表中 将当前温度放置在缓冲表和记录中,但只允许网页访问缓冲表
它可能不那么准确,但希望差别不大,但你应该看到速度大幅提高是的。尝试使用范围查询