业务需求是这样,app 应用是有点赞,评论,at 我 评论 消息 现在用户量上来了,以前这些消息都存一个表 ( id,user_id,type (消息类型),subject_id(类型),readStatus(阅读状态))
现在有差不多七百多万消息,每个人读取自己的未读消息数量 性能会下降,只能建立索引去 count idx(type,readStatus,user_id),目前做了 mysql 分区,按用户 hash 到 20 个分区上面,二级索引文件比较大
还有每个用户消息列表要拉取第一页消息 select * from message where user_id = :userId and type=:type order by create_time desc 这个语句也会建立索引
分表的话要还是要建立索引,不知道大家项目是不是这样做,还有发现分区和分表建立二级索引最大的区别是分区是在几百万数据建立索引,而分表是每个表都要建一个索引
1
zoharSoul 2022-06-06 16:28:43 +08:00
你是在提问, 还是在科普?
|
2
npe 2022-06-06 16:30:05 +08:00
有时候换种思路豁然开朗,即:未读消息大于 1000 时显示 999+
|
4
simonlu9 OP @npe 也做了这个优化,select count(1) from (select 1 from sys_message_user where user_id = :userId and `type` = :type and read_status = :readStatus limit 100 ) t
|
5
meta 2022-06-06 17:07:42 +08:00
没看懂你这个是要取得消息还是要取得消息的数量,如果只是要取得数量的话,单独做一个计数器不就行了
|
6
xiaoyangsa 2022-06-06 17:46:49 +08:00
直接在缓存里做增减嘛。user,type,un_read_count
或者单独弄个表,内容也是上面那个。免得去拉数据库 |
7
NULL2020 2022-06-06 17:48:47 +08:00
未读消息 id 存 redis 里,每个用户一份,拉取未读消息数只需要一个 redis 命令,用户拉取消息列表时,清理对应的未读消息
|
8
git00ll 2022-06-06 21:57:02 +08:00
单独为每个用户维护一个 count , 用户点进消息的时候再从数据库查询
|
10
hetal 2022-06-07 13:57:52 +08:00
几百万数据就分区了?让我上亿条的无识的人情何以堪
|
11
simonlu9 OP @MoYi123 写应该没什么问题,就是如果系统刚刚好有一个用户是客服,然后很多人都给他发信息,堆积消息未读数有十几万条,基本上扫索引也很慢的,因为 readstatus 就两种状态,基本上索引也要全扫描,后面改成扫描 100 条显示 99+算是个比较偷懒的方法
|
12
simonlu9 OP @meta 一个是获取用户各消息类型的未读消息数,一个是获取各类型的消息列表第一页(按时间倒序),分区的话都要建立这两个索引,代价是索引越来越大
|
13
issakchill 2022-06-07 16:14:31 +08:00
之前做过一个很简易的 im
未读消息的消息 id 存 redis 拉取未读消息的时候直接 in 这些 ids |