我想问一个有关如何在使用InnoDB引擎大MySQL表提高性能的问题:提高性能的一大MySQL表
中目前我的数据库有大约200万行的表。该表格定期存储由不同传感器收集的数据。该表的结构如下:
CREATE TABLE sns_value (
value_id int(11) NOT NULL AUTO_INCREMENT,
sensor_id int(11) NOT NULL,
type_id int(11) NOT NULL,
date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
value int(11) NOT NULL,
PRIMARY KEY (value_id),
KEY idx_sensor id (sensor_id),
KEY idx_date (date),
KEY idx_type_id (type_id));
起初,我还以为在几个月分区表的,但由于稳定增加新的传感器,将在一个月左右达到目前的规模。
我想出的另一个解决方案是通过传感器对表格进行分区。但是,由于MySQL的1024个分区的限制,这不是一个选项。
我认为,正确的解决办法是使用具有相同结构的表中的每个传感器:
sns_value_XXXXX
这样将有超过1000台3000万的估计大小每年行数。同时,这些表格可以在几个月内进行分区,以便最快速地访问数据。
该解决方案会产生哪些问题?是否有更规范的解决方案?
编辑附加信息
我认为表是关于大到我的服务器:
- 云2xCPU和8GB内存
- LAMP(CentOS的6.5和MySQL 73年5月1日)
每个传感器可能有多个变量类型(CO,CO2等)。
我主要有两个慢查询:
1)为每个传感器和类型(平均,最大值,最小值)每日摘要:
SELECT round(avg(value)) as mean, min(value) as min, max(value) as max, type_id
FROM sns_value
WHERE sensor_id=1 AND date BETWEEN '2014-10-29 00:00:00' AND '2014-10-29 12:00:00'
GROUP BY type_id limit 2000;
这需要超过5分钟以上。
2)垂直到水平视图和出口:
SELECT sns_value.date AS date,
sum((sns_value.value * (1 - abs(sign((sns_value.type_id - 101)))))) AS one,
sum((sns_value.value * (1 - abs(sign((sns_value.type_id - 141)))))) AS two,
sum((sns_value.value * (1 - abs(sign((sns_value.type_id - 151)))))) AS three
FROM sns_value
WHERE sns_value.sensor_id=1 AND sns_value.date BETWEEN '2014-10-28 12:28:29' AND '2014-10-29 12:28:29'
GROUP BY sns_value.sensor_id,sns_value.date LIMIT 4500;
这也需要超过5分钟。
其他考虑
- 时间戳可能由于插入件的特性进行重复。
- 定期插入必须与选择共存。
- 没有更新或删除在表上执行。
的假定的制造“一个表中的每个传感器”的方法
- 表针对每个传感器会小得多,以便访问会更快。
- 每个传感器只能在一张桌子上进行选择。
- 选择来自不同传感器的混合数据对时间要求不高。
更新2015年2月2日
我们已经创建了一个新表,每年的数据,这是我们也每天划分为。每张桌子大约有2.5亿行,有365个分区。使用的新索引与Ollie建议的(sensor_id,date,type_id,value)一样,但查询仍然需要30秒到2分钟。我们不使用第一个查询(每日摘要),仅使用第二个查询(垂直到水平视图)。
为了能够对表格进行分区,必须删除主索引。
我们错过了什么吗?有没有办法提高性能?
非常感谢!
当前结构发生了什么问题? – 2014-10-28 17:57:08
大?这里很大吗? – TomTom 2014-10-28 18:16:12
teis数据的用途是什么?你应该怎么读? – Aret 2014-10-28 19:28:18