如何在低规格系统上的大表上提高 MySQL 性能?
Posted
技术标签:
【中文标题】如何在低规格系统上的大表上提高 MySQL 性能?【英文标题】:How can I improve MySQL performance on a lrge table on low spec system? 【发布时间】:2015-03-19 08:06:50 【问题描述】:我有一个 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 抱有太大期望,或者我可以做些什么来改进我的设置?
【问题讨论】:
是的。尝试使用 RANGE 查询 【参考方案1】:罪魁祸首是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!
【讨论】:
【参考方案2】:调用DATE()
之类的方法会立即给您带来麻烦。这些不能被索引,没有索引你死在水里。
如果您经常调用这些,请创建一个 DATE
列,其中包含您正在搜索的数据。您可能还需要一个列来捕获要提取的小时信息。
数据库规范化原则一直适用,直到您遇到这样的情况,即理想形式的速度慢得令人无法接受。在这种情况下,您需要仔细去规范化以解决这些问题。保持这样的数据同步可能很棘手,因此请确保在更改主日期时使所有这些派生列保持最新。
如果您可以将DATETIME
缩小到某个时间范围,您可能有机会按原样使用它,例如:
WHERE timeRecorded BETWEEN '2015-01-20 20:00:00' AND '2015-01-20 20:59:99'
如果可行,您现有的索引将适用。
【讨论】:
【参考方案3】:我认为您所追求的可以在 Raspberry Pi 上实现,您只需要更改处理繁重查询的方式即可。
如果是历史数据,则每天处理数据并将其保存到另一个(更小、更快)的表格中,以便网页快速引用。
每小时平均值也仅每小时运行一次,保存到单独的表格中。
将当前温度和记录放在缓冲表中,但只有网页可以访问缓冲表。
它可能不那么准确,但希望差异会很小,但您应该会看到速度大幅提升
【讨论】:
以上是关于如何在低规格系统上的大表上提高 MySQL 性能?的主要内容,如果未能解决你的问题,请参考以下文章