最代码官方
2015-12-12 19:56:20
原证精
最代码网站用户私信列表采用mysql union查询优化为Redis查询的经验和相关代码片段分享
由于用户和私信的数据量逐渐增加,查询用户和其他用户的私信合并排重排序的sql语法给mysql带来了很大的压力,springdata jpa的hql查询语法如下:
select id from (select id,target_id,case when user_id=?1 and type=?2 then 'sender' else 'receiver' end flag from javaniu_post where user_id=?1 and type=?2 union select id,user_id,case when user_id=?1 then 'sender' else 'receiver' end flag from javaniu_post where target_id=?1 and type=?2 order by id desc) as ret group by target_id order by id desc
在mysql的slow查询中经常会出现10s以上的记录:
mysql查询性能的瓶颈在于某个用户和其他用户之间交互越多,发送私信越多,mysql union查询参与运算的集合数据量会越大,性能也会越来越低。
数据变化如下:
1.用户A发给用户B生成私信1
用户A->用户B->私信1
2.用户A发给用户C生成私信2
用户A->用户C->私信2
3.用户A发给用户E生成私信3
用户A->用户E->私信3
4.查询用户A的私信列表
私信3,私信2,私信1
5.用户B发给用户A生成私信4
用户B->用户A->私信4
6.查询用户A的私信列表
私信4,私信3,私信2
私信1因为有最新数据私信4的存在,所以不会返回。
所以迫切需要引入新的技术来解决该查询的性能瓶颈,想到了流行的redis技术,于是修改设计如下:
模拟发私信的数据结构如下
127.0.0.1:6379> zadd uid1 1 2 (integer) 1 127.0.0.1:6379> zadd uid1 2 3 (integer) 1 127.0.0.1:6379> zadd uid1 3 5 (integer) 1 127.0.0.1:6379> zrevrange uid1 0 -1 1) "5" 2) "3" 3) "2" 127.0.0.1:6379> zrevrange uid1 0 -1 withscores 1) "5" 2) "3" 3) "3" 4) "2" 5) "2" 6) "1" 127.0.0.1:6379> zadd uid1 4 2 (integer) 0 127.0.0.1:6379> zrevrange uid1 0 -1 withscores 1) "2" 2) "4" 3) "5" 4) "3" 5) "3" 6) "2" 127.0.0.1:6379>
注意:把私信id做为score来做排序
相关代码片段如下:
删除或添加私信时:
String uid = t.getUserId() + ""; String type = ModuleConstants.POST_TYPE_MESSAGE + ""; String tgid = t.getTargetId() + ""; long id = t.getId(); long time = t.getCreateTime().getTime(); String po_uid_tp_tgid = String.format( RedisConstants.POST_USERID_TYPE_TARGETID, uid, type, tgid); // from uid String po_uid_tp = String.format(RedisConstants.POST_USERID_TYPE, uid, type); // to uid String po_tgid_tp = String.format(RedisConstants.POST_USERID_TYPE, tgid, type); if (t.getStatus() == ModuleConstants.MODULE_STATUS_DELETED) {// 删除私信同时要删除redis zsetOps.remove(po_uid_tp_tgid, id + ""); zsetOps.remove(po_uid_tp, tgid); zsetOps.remove(po_tgid_tp, uid); } else { zsetOps.add(po_uid_tp_tgid, id + "", time); zsetOps.add(po_uid_tp, tgid, id); zsetOps.add(po_tgid_tp, uid, id); }
查询用户的私信时:
String uid = userId + ""; String tp = ModuleConstants.POST_TYPE_MESSAGE + ""; String po_uid_tp = String.format(RedisConstants.POST_USERID_TYPE, uid, tp); int total = zsetOps.zCard(po_uid_tp).intValue(); int ps = total / count + (total % count > 0 ? 1 : 0); if (page > ps) { page = ps; } int start = (page - 1) * count; int end = page * count - 1; Set<TypedTuple<String>> _ids = zsetOps.reverseRangeWithScores( po_uid_tp, start, end); List<Long> ids = new ArrayList<Long>(); Iterator<TypedTuple<String>> iterator = _ids.iterator(); while (iterator.hasNext()) { TypedTuple<String> _id = iterator.next(); long id = _id.getScore().longValue(); ids.add(id); } List<Post> ts = (List<Post>) findAllByIds(ids); Pageable pageable = new PageRequest(page - 1, count); Page<Post> _page = new PageImpl<Post>(ts, pageable, total); initBeans(_page.getContent());
redis查询最代码官方,id=1的所有私信列表,和mysql union运算的结果完全一致,但是性能可是天壤之别:
相关资料和代码:
猜你喜欢
- mysql创建多列索引查询百万表数据的性能优化经验分享
- mysql经纬度查询并且计算2KM范围内附近用户的sql查询性能优化实例教程
- 最代码网站中在线提醒的机制优化经验及其相关源代码片断分享
- java程序中字符串比较常见的四种判断是否为空的性能优化比较
- 最代码官方网站首页静态页面
- 最代码网站被第三方垃圾广告网站恶意反链处理的经验分享和代码片段分享
- 最代码网站中关于动态表event的设计思路
- Mysql低效的where 1=1性能测试
- java多线程ReentrantLock、sync、ReentrantReadWriteLock性能比较
- java对比IO和NIO的文件读写性能测试
- java HashMap四种遍历查询方式耗时性能对比
- 最代码愚人节首页旋转倾斜特效代码分享
请下载代码后再发表评论
相关代码
- 原证精 最代码网站中在线提醒的机制优化经验及其相关源代码片断分享
- 原证精 最代码网站被第三方垃圾广告网站恶意反链处理的经验分享和代码片段分享
- 原证 最代码官方网站首页静态页面
- 原证精 最代码网站中关于动态表event的设计思路
- 原证 最代码网站的链接被垃圾广告链接恶意提交到百度收录后的经验和代码片段分享
- 证 2012年度java牛用户贡献排行版
- java牛官方想开发一个全部开源的系统
- 证 最代码愚人节首页旋转倾斜特效代码分享
- java牛每日注册用户数
- 原证精 flex小型消息通知框架miniNotice最代码首发
- 原 chrome浏览器插件实现几行脚本批量赞最代码心情
- 原 java通过jsoup爬取最代码牛币兑换活动
最近下载
最近浏览
浪里格朗 LV4
2023年1月31日
yanxiaoai LV6
2023年1月24日
zz1230012300 LV11
2022年8月29日
locklock LV2
2022年6月23日
2500743843
2022年6月1日
暂无贡献等级
12345670
2022年4月10日
暂无贡献等级
itcaizhe LV9
2021年10月28日
glqywy1 LV4
2021年10月25日
廖业贵 LV18
2021年6月28日
2840820049 LV9
2021年6月9日