MySQL-千万要统一表字段的排序规则

Snipaste_20240125_134647.png

起因

上周五人还在北京参加“DTC-数据库嘉年华”,下午突然接到公司电话说数据库炸了。
运维反馈数据库上出现了大量慢SQL,整个数据库几乎hang住。经过协助远程排查,异常SQL源头如下(已脱敏)

SELECT
	count( DISTINCT gm.id ) AS num 
FROM
	xxx_material gm
	LEFT JOIN xxx_group_data_collection gdc ON gm.data_id = gdc.id
	LEFT JOIN xxx_info gi ON gi.goods_sign_last = gdc.product_id
	LEFT JOIN xxx_goods_store AS gs ON gs.info_id = gi.id 
WHERE
	( gdc.is_delete = 0 AND gdc.platform != 2 AND gdc.price > 0 ) 
	AND ( gm.room_id = 'xxxxx@chatroom' AND gm.uid = 0 ) 
	AND gm.create_time > date(
	now())

跟开发对接后,说该SQL已经在线上稳定运行大半年了,正常情况下毫秒级。说刚刚只做了一个相关操作
提交yearning修改了gdc.product_id该字段的长度。yearning内容如下

ALTER TABLE `xxx_goods_center`.`xxx_group_data_collection` MODIFY COLUMN `product_id` varchar(55) NOT NULL COMMENT '商品id 淘宝的后半段';

按理说只修改字段长度是没有什么影响的,只能先从执行计划入手

1 SIMPLE gm ref data_id,idx_room_id,idx_create_time,idx_uid idx_room_id 602 const 1 5.00 Using where
1 SIMPLE gdc eq_ref PRIMARY PRIMARY 4 dtkdb_goods_center.gm.data_id 1 5.00 Using where
1 SIMPLE gi ALL idx_goods_sign_last 696332 100.00 Range checked for each record (index map: 0x2)
1 SIMPLE gs ref idx_infoid idx_infoid 4 dtkdb_goods_center.gi.id 2 100.00 Using where; Using index

注意看加粗这行,说明关联时没有走到索引。
可能因为最近处理不走索引的情况比较多吧,第一时间想到可能是字符集或排序规则引起的。
查询两个字段的字符集、排序规则,果然不一样。

goods_sign_last utf8mb4 utf8mb4_0900_ai_ci
product_id utf8mb4 utf8mb4_bin

修改为相同排序规则后数据库恢复正常。

复盘

但是为什么改了字段长度排序规则就变了呢,经排查xxx_group_data_collection 表的字符集和排序规则为utf8mb4 utf8mb4_bin,由于在修改字段长度时没有指定字符集和排序规则,导致字段的字符集、排序规则默认使用了表的规则,从而导致原本正常的SQL变成了慢SQL。

思考

事后思来想去该问题在当时几乎无法避免。

  • 这条SQL变更本身并没有什么问题,只是修改字段长度而已
  • 每个单表在建立之初可能不需要与其他表关联,那么从设计规范出发就按最初的业务分配最合理的属性(字段长度、字符集、排序规则)
  • 随着业务迭代,确实需要多表关联时发现关联字段属性不一样,这几乎在任何公司都会发生
  • 如果每条SQL都要去核对表、字段的字符集又会大大影响开发效率

综上几点,后续我司应该会统一表、字段的字符集、排序规则。牺牲掉“最合理”性,从而保证易用性。

彩蛋

其实很多场景都是牺牲掉“最合理”性,从而保证易用性,例如数据库的三大范式,通常我们只需要满足前两项即可,如果强制每个数据库表设计都满足三大范式,反而画蛇添足了。

在这里插入图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值