我使用的MySQL5.6在事务表(innodb)中有大约1.5亿条记录。随着大小的增加,此表变得不可管理(添加列或索引),而且速度很慢,即使有必要的索引。在互联网上搜索后,我发现现在是划分表的适当时机。我是密友,分区将为我解决以下目的
提高dml语句响应时间(使用分区修剪)
改进归档流程
但我不确定它是否(以及如何)提高这个表的ddl性能。更具体地说是遵循ddl的性能。
alter table add/drop列
更改表添加/删除索引
我浏览了mysql文档和互联网,但找不到我的答案。任何人都可以帮助我在这方面或提供任何相关的文件。
我的表结构如下
CREATE TABLE `TRANSACTION` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`parent_uuid` char(36) DEFAULT NULL,
`order_number` varchar(64) DEFAULT NULL,
`order_id` int(11) DEFAULT NULL,
`order_uuid` char(36) DEFAULT NULL,
`order_type` char(1) DEFAULT NULL,
`business_id` int(11) DEFAULT NULL,
`store_id` int(11) DEFAULT NULL,
`store_device_id` int(11) DEFAULT NULL,
`source` char(1) DEFAULT NULL COMMENT 'instore, online, order_ahead, etc',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`flags` int(11) DEFAULT NULL,
`customer_lang` char(2) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`),
KEY `business_id` (`business_id`,`store_id`,`store_device_id`),
KEY `parent_uuid` (`parent_uuid`),
KEY `order_uuid` (`order_uuid`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
我使用下面的语句进行分区。
ALTER TABLE TRANSACTION PARTITION BY RANGE (id)
(PARTITION p0 VALUES LESS THAN (5000000) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (10000000) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
谢谢!
1条答案
按热度按时间qnakjoqk1#
分区不是性能万灵药。即使你提到的项目也不会加速;他们甚至会放慢脚步。
相反,我将对表格进行评论,以寻找加速某些事情的方法。
一旦uuid上的索引变得太大而无法缓存,它的性能就会很差。这是因为它的随机性。可能的解决方案:将其压缩为
BINARY(16)
; 以其他方式缩小table;避免UUID。为什么两者都有
parent_id
以及parent_uuid
??缩小4字节
INTs
在可行的情况下使用较小的数据类型。通常
CHAR
应该是CHARACTER SET ascii
(1字节/字符),非utf8mb4
(4字节/字符)。警告:1.5亿正在接近20亿美元的极限
INT SIGNED
. 考虑4b限制INT UNSIGNED
. (每个是4个字节。)你用过吗
created_at
或者updated_at
?mysql 8.0.13有一个非常快速的
ADD COLUMN
以及DROP COLUMN
(对于有限的情况)。5.7.?? 侵入性较小
ADD INDEX
但我不确定它是否适用于分区表。5.7.4:在线ddl支持减少了表重建时间并允许并发dml,这有助于减少用户应用程序停机时间。有关更多信息,请参阅联机ddl概述。
更重要的是,让我们看看“太慢”的主要查询。可能会有复合索引和/或查询的重新格式化来加速它们。
分区甚至很有可能会有所帮助,但实际上却没有
PRIMARY KEY
.我认为只有4个用例分区有助于提高性能。