MySQL 5.7 Key分区数据不均问题及分区判定逻辑咨询
问题描述
我创建了8个KEY分区,但数据分布严重失衡:p0、p2、p4、p6分区占据了99.98%的数据行,而p1、p3、p5、p7分区仅占0.02%。我需要解决该问题,因此想明确MySQL 5.7执行SELECT语句时确定目标分区的具体计算逻辑,同时寻求能使分区数据分布均匀的优化方案。已知KEY分区基于MD5与取模实现,但想搞清楚MySQL的实际计算流程。
MySQL 5.7 KEY分区的分区计算逻辑
对于KEY分区,MySQL 5.7的实际计算流程如下:
- 首先对分区键(如你的表中
wId或workspaceId)计算内部哈希值:注意这不是直接调用MD5()函数,MySQL有自己实现的哈希算法,但对于字符串类型的分区键,其哈希结果与MD5存在相关性。 - 将哈希值对分区总数(
PARTITIONS子句指定的数值)取模,余数即为目标分区的索引(从0开始计数)。 - 执行SELECT语句时:
- 如果查询条件包含分区键的等值/范围条件,MySQL会通过上述逻辑直接定位到对应分区;
- 如果查询条件未包含分区键,则会扫描所有分区。
数据分布不均衡的优化方案
- 核查分区键的分布特性:先统计
wId的实际数据分布,看是否存在少数wId占据绝大多数数据的情况。如果wId本身就高度集中,无论哈希如何处理,分区都会失衡。 - 更换或调整分区键:
- 若单字段
wId的哈希分布不佳,可改用复合分区键(如(wId, dId)),通过组合字段的哈希值分散数据; - 选择本身分布更均匀的字段作为分区键,比如
createdAt(需注意KEY分区对日期类型的哈希逻辑)。
- 若单字段
- 调整分区数量:
- 避免使用2的幂次(如8)作为分区数,这类数值容易放大哈希值低位分布不均的问题;
- 优先选择质数作为分区数(如7、11),能有效降低哈希冲突导致的分布失衡概率。
- 手动控制哈希逻辑:如果必须保留当前分区键,可在插入数据时对
wId进行预处理,比如取MD5(wId)的特定片段再取模,或添加随机后缀后再哈希,人为打散数据分布。但此方法需同步修改查询时的分区定位逻辑。 - 改用HASH分区:相对于KEY分区的自动哈希,HASH分区允许自定义哈希函数,例如:
你可以完全控制哈希逻辑,选择更均匀的哈希方式来分散数据。PARTITION BY HASH(MD5(wId)) PARTITIONS 11;
附:表结构与执行计划
表结构
WD表
CREATE TABLE `WD` ( `dId` varchar(120) NOT NULL, `wId` varchar(120) NOT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, PRIMARY KEY (`wId`,`dId`), KEY `idx_WD_w_d` (`wId`,`dId`), KEY `idx_WD_d_w` (`dId`,`wId`), KEY `idx_WD_w_u` (`wId`,`updatedAt`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 /*!50100 PARTITION BY KEY (workspaceId) PARTITIONS 11 */
DA表
CREATE TABLE `DA` ( `id` varchar(120) NOT NULL, `wId` varchar(120) NOT NULL, `subject` varchar(180) NOT NULL, `dId` varchar(120) NOT NULL, `createdAt` datetime NOT NULL, `updatedAt` datetime NOT NULL, PRIMARY KEY (`id`,`workspaceId`), KEY `idx_DA_w_s_d` (`workspaceId`,`subject`,`documentId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 /*!50100 PARTITION BY KEY (wId) PARTITIONS 11 */
执行计划(中文表头)
id 查询类型 表名 分区 访问类型 可能用到的索引 使用的索引 索引长度 关联引用 行数 过滤比例 额外信息 1 SIMPLE WD p1 ALL PRIMARY,idx_WD_w_d,idx_WD_d_w,idx_WD_w_u NULL NULL NULL 1 100.00 Using where; Using filesort 1 SIMPLE DA p1 ref idx_documentAcl_w_s_d idx_documentAcl_w_s_d 1266 const,const,DocumentService.WD.documentId 1 100.00 Using index
内容的提问来源于stack exchange,提问作者Coalery
相关产品推荐
相关产品推荐

