1,游戏的事件表的桶分布不均匀,数据倾斜严重,导致加字段直接卡死。
解决方法:
- 如果要加4个字段,要分4次执行,而不是一次性执行四个加字段的SQL。
- 改变桶的数量保持每个桶只有每个桶的磁盘占用只有2gb内存。
2,where 添加有函数,导致需要多扫描几个分区
业务场景,需要查询最近30天的某个用户的登录
第一个需要扫描所有分区:
explain
SELECT *
FROM one_data_prod.game_event_tb
WHERE part_date >= (SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 32 DAY), '%Y-%m-%d'))
AND part_date <= (SELECT CURDATE())
AND event_name = 'role_login'
and event_time <= '2025-02-10 08:41:07'
and role_id in (1111)
order by event_time desc
limit 1;
第二个只扫描,几个分区
explain
SELECT *
FROM one_data_prod.game_event_tb
WHERE part_date >= '2025-01-09'
AND part_date <= '2025-02-10'
AND event_name = 'role_login'
and event_time <= '2025-02-10 08:41:07'
and role_id in (1111)
order by event_time desc
limit 1;
结论:where 后面的条件,不要涉及函数,否则会多扫描几个分区
3,调整表分区的分桶数未生效,执行语句后提示优化失败,操作被取消或超时。
【原因分析】数据量较大导致操作过程中消耗的存储和内存较高,磁盘空间不足,以及执行时长超时。
【解决方案】
1、增加磁盘空间,确保有足够的存储空间进行操作。
2、在业务低峰期执行操作,减少对业务的影响。
3、调整全局查询超时时间,例如设置set global query_timeout = 1800;,以确保操作有足够的时间完成。
4、执行完成后,将全局查询超时时间改回默认值300
4,100亿的表,占用4TB的内存,加索引加不上
因为边加索引,边写入,事务执行时间太长了,加了3天都没执行完。
所以
1,event_tb 重命名为 event_tb_back
2,创建一个 一模一样的镜像 表: CREATE TABLE event_tb
3, event_tb_back 的 加索引
4,rename table event_tb to event_tb_new
rename table event_tb_back to event_tb
5,把临时表的数据 导回原始表
INSERT INTO event_tb select * FROM event_tb_new