千万级历史数据跑报表 性能优化方案
各位社区的大佬:
小弟 现在有个千万数据量的会员表,有注册时间及注册渠道。现在有个业务需求需要把这些数据清洗到数据报表(数据表)里面
数据报表格式如下
register_date | register_channel | count |
---|---|---|
2020-01-01 | 1 | 10 |
2020-01-01 | 2 | 13 |
2020-01-02 | 1 | 12 |
2020-01-02 | 2 | 11 |
… | … | … |
目前我的做法是查询表里最早注册时间循环至当前时间,在循环里面查询日期下 ->groupBy('registered_channel')->selectRaw('registered_channel as register_channel, count(1) as register_num')
渠道 及渠道注册人数;
不知各位还有什么更好的优化方案
新建一张表,把数据按格式导入到新表里,每日凌晨更新一次
你用循环就注定你的速度不会快
你先分批次清洗数据 然后放入一个队列 一次插入多条数据 看你业务需求
不需要实时查询的话,将数据分批归档不就好了吗?而且归档过的数据不会变动的
group by 数据库不会蹦么?给出如下伪代码:
创建一个表记录已经清洗数据的id,清洗结果,失败原因, 然后定时去执行脚本去刷(脚本取记录表里不存在id的分块)
千万级的mysql还行啊,时间建个索引 你可以按照月写个循环,按照insert into select 这种形式到个新表应该不是问题
说一下我们项目当前的做法吧 (用户登录活跃统计)
要求: 每天凌晨统计昨天一天的数据,统计好放到 daily 中
实现:
chunk()
或 手动limit
方式分块查询;如果可以在 sql 中计算,则视情况用group by
等daily
表中,然后再用id > 1000000
和created_at between
查出max(id)
保存下来,方便用于明天第一步的使用。注意项: 因为
created_at
是 timestamp 字段,加索引也不怎么管用,而主键索引很好用