由于用户和私信的数据量逐渐增加,查询用户和其他用户的私信合并排重排序的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=?1then '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> _ids = zsetOps.reverseRangeWithScores(

po_uid_tp, start, end);

List ids = new ArrayList();

Iterator> iterator = _ids.iterator();

while (iterator.hasNext()) {

TypedTuple _id = iterator.next();

long id = _id.getScore().longValue();

ids.add(id);

}

List ts = (List) findAllByIds(ids);

Pageable pageable = new PageRequest(page - 1, count);

Page _page = new PageImpl(ts, pageable, total);

initBeans(_page.getContent());

redis查询最代码官方,id=1的所有私信列表,和mysql union运算的结果完全一致,但是性能可是天壤之别:

info的memory截图和keyspace截图

相关资料和代码:

mysql和redis统计网站活跃度,最代码网站用户私信列表采用mysql union查询优化为Redis查询的经验和相关代码片段分享...相关推荐

  1. golang mysql 插入_Mysql学习(一)添加一个新的用户并用golang操作Mysql

    Mysql添加一个新的用户并赋予权限 添加一个自己的用户到mysql 首先我们需要先用root用户登录mysql,但是刚安装完没有密码,我们先跳过密码 ailumiyana@ailumiyana:~/ ...

  2. html提交列表编号自动生成目录,解析 Html 自动生成目录 TOC 的相关代码

    解析 Html 自动生成目录 TOC 的相关代码 相关代码function create_content_TOC(dom, config, target) { let hList = dom.find ...

  3. centos 7 mysql界面管理器_centos7安装mysql5.7.24,并使用system管理mysql

    1.创建安装目录 mkdir /mysql 2.进入安装目录 cd /data 3.下载5.7.24的tar包 wget https://downloads.mysql.com/archives/ge ...

  4. linux mysql 匿名用户_Linux下安装mysql

    linux版本:CentOS7 64位 1.下载安装包"mysql-5.6.33-linux-glibc2.5-x86_64.tar.gz # 安装依赖 yum -y install per ...

  5. PHP+MySQL实现精确统计网站访问量(IP个数)

    基于WordPress的网站有很多统计功能.但是只能统计文章阅读数.不能统计访客人数.以下代码可以实现获取来访用户的IP地址,一个IP对应一次访问.即使刷新也不会增加访问量.这个非常精确. 1.创建一 ...

  6. 使用 Redis 统计网站 UV 的方法

    文章目录 前言 思路 HyperLogLog 使用 Redis 命令操作 使用 Java 代码操作 HyperLogLog 实现原理及特点 使用 Java 实现 HyperLogLog 小结 前言 网 ...

  7. redis统计用户日活量_玩转Redis-HyperLogLog统计微博日活月活

    <玩转Redis>系列文章主要讲述Redis的基础及中高级应用.本文是<玩转Redis>系列第[9]篇,最新系列文章请前往公众号"zxiaofan"查看,或 ...

  8. 拼多多面试:如何用 Redis 统计独立用户访问量?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:沙茶敏碎碎念 来源:https://url.cn/5tQPE ...

  9. 使用redis和mysql的开源项目_干货!带你了解为什么那么多开源项目都是用Redis!...

    很多开源项目中都使用了redis,这些项目为什么使用redis?使用redis有什么好处?怎么使用redis?带着这些疑问,我们来了解一下redis. 一.什么是Redis Redis是一个免费开源用 ...

最新文章

  1. 人工智能微控制器体系结构
  2. Vijos P1131 最小公倍数和最大公约数问题【暴力】
  3. 第二阶段_第五小节_C#基础3
  4. django ORM 操作
  5. JAVA程序员面试必知32个知识点
  6. 双向链表中插入结点并输出
  7. linux入门 适合初学者_【推荐】适合初学者临摹的国画|国画基础入门教学视频教程!...
  8. 毕业论文范文计算机,计算机毕业论文范文参考
  9. Visual Studio 2008创建项目(ATL)
  10. ie8 js未指明的错误_DD_belatedPNG IE8 js报错问题解决
  11. 数据库--Oracle
  12. 项目管理知识体系指南(第六版PMBOK 指南)目录
  13. 【CS229 Deep Learning笔记】二. 介绍:分类问题
  14. 【友元、异常和其他】——C++ Prime Plus CH15
  15. 《西游记》中师徒四人的形象探究及现实意义
  16. XmlHttp的open( )方法
  17. c++重写卷积网络的前向计算过程,完美复现theano的测试结果
  18. border-radius的使用
  19. 用于播放视频的Html5元素是,HTML5多媒体播放video元素与audio元素详解
  20. Landsat系列卫星:Landsat 9 详解和细节(NASA/USGS)

热门文章

  1. 为什么说百度教育大脑3.0,是中国教育迎来的真正智慧大脑?
  2. 知识星球作业(第5周) - 关于view的知识
  3. 【命令】usemod 的用法
  4. Spark源码阅读02-Spark核心原理之监控管理
  5. mysql分组后统计
  6. anaconda配置环境变量
  7. python全栈 day09随笔
  8. 团队-象棋游戏-模块开发过程
  9. 【二维树状数组】See you~
  10. 你的应用是如何被替换的,App劫持病毒剖析