处理几天内并发读/写非常频繁的3b rec表的好方法是什么?
Linux服务器,运行MySQL v8.0.15。
我有此表将记录设备数据历史记录。该表需要将其数据保留一年,可能两年。增长率非常高:8,175,000 rec / day(1mo = 245m rec,1y = 2.98b rec)。在设备数量增加的情况下,该表有望能够处理它。在过去几天内,表读取非常频繁,超过一个星期后,此频率显着下降。
[在此表上有多个并发连接可供读写,并且r / w的目标彼此之间非常接近,因此发生了死锁/表锁定,但已解决(重试,事务大小较小)。] >
我现在正在使用每日分区,因为读取几乎不跨越> 1个分区。但是,分区太多,无法保留1年数据。使用cron可以按计划创建或删除分区。
CREATE TABLE `table1` ( `group_id` tinyint(4) NOT NULL, `DeviceId` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL, `DataTime` datetime NOT NULL, `first_log` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `first_res` tinyint(1) NOT NULL DEFAULT '0', `last_log` datetime DEFAULT NULL, `last_res` tinyint(1) DEFAULT NULL, PRIMARY KEY (`group_id`,`DeviceId`,`DataTime`), KEY `group_id` (`group_id`,`DataTime`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci /*!50100 PARTITION BY RANGE (to_days(`DataTime`)) ( PARTITION p_20191124 VALUES LESS THAN (737753) ENGINE = InnoDB, PARTITION p_20191125 VALUES LESS THAN (737754) ENGINE = InnoDB, PARTITION p_20191126 VALUES LESS THAN (737755) ENGINE = InnoDB, PARTITION p_20191127 VALUES LESS THAN (737756) ENGINE = InnoDB, PARTITION p_future VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
插入的大小为〜1500 /批:
INSERT INTO table1(group_id, DeviceId, DataTime, first_result) VALUES(%s, %s, FROM_UNIXTIME(%s), %s) ON DUPLICATE KEY UPDATE last_log=NOW(), last_res=values(first_result);
选择主要是通过
DataTime
或DeviceId
来计数,以特定分区为目标。
SELECT DataTime, COUNT(*) ct FROM table1 partition(p_20191126) WHERE group_id=1 GROUP BY DataTime HAVING ct<50; SELECT DeviceId, COUNT(*) ct FROM table1 partition(p_20191126) WHERE group_id=1 GROUP BY DeviceId HAVING ct<50;
所以问题:
注意:我已经读过this堆栈问题,拥有多个表是很痛苦的,因此,如果没有必要,我希望不要破坏该表。另外,目前无法进行分片。
处理几天内并发读写非常频繁的3b rec表的好方法是什么? Linux服务器,运行MySQL v8.0.15。我有此表将记录设备数据历史记录。 ...
首先,INSERTing
100条记录/秒是潜在的瓶颈。我希望您正在使用SSD。让我看看SHOW CREATE TABLE
。说明数据如何到达(批量,一次,从多个来源等),因为即使有SSD,我们也需要讨论批处理输入行。