资讯专栏INFORMATION COLUMN

我是这样优化用户关系查询的

lauren_liuling / 864人阅读

摘要:优化结果计算机器六代内存时间秒优化版本使用存放用户,通过命令获取下级时间复杂度,是所有给定集合的成员数量之和。

0x01

我们有一个业务场景是需要将用户邀请的下级用户根据其用户等级给统计出来(不止统计一级).
现有的解决方案:
mysql中一张用户表
主要的3个字段:user_id, parent _id,level,
典型的一个树形结构.
因为数据量很大,查询次数很多,所以重算这数据基本上重算一次要花个几分钟.

0x02

优化版本1:
假如我将没所有用户对应的所有直接下级用户的id取出,存放到redis中的数组,像这样

U:110->[111,112,113,...]

将用户等级也放到redis中,像这样

L:110->0

然后通过map的方式取到下级的下级用户并合并起来,再通过用户等级进行分组。

users.stream.map(u-> jedis.lrange(0,-1)).flatMap(u-> u).collect(grouppingBy(u-> jedis.get("L:" + u)))...

LRANGE
时间复杂度:O(S+N), S 为偏移量 start , N 为指定区间内元素的数量。`
优化结果:
计算机器:I5 六代 8G内存
时间:25秒

0x03

优化版本2:
使用Set存放用户,通过SUNION命令获取下级ID

时间复杂度:O(N), N 是所有给定集合的成员数量之和。

获取当前下级的用户代码则更简单了,首先将当前用户通过CPU并行的方式把SET的key计算出来,然后通过SUNION将所有的用户取出来:

private Set downLevelAllUser(Set users) {
    return jedis.sunion(users.parallelStream().map(s ->
            "U:" + s
    ).collect(Collectors.toList()).toArray(new String[0]));
}

这些用户的等级都查出来,那就获取他们的用户等级并进行分组.

private Map> groupUser(Set users) {
    return jedis.mget(users.parallelStream().map(u -> "L:" + u)
            .collect(Collectors.toList()).toArray(new String[0]))
            .parallelStream().collect(Collectors.groupingBy(r -> r));
}

主要功能都实现了,那么试试计算8级所花时间

public List> downLevel8UserRole(int start_user) {
        Set u1 = downLevel1Users(start_user);
        Map> m1 = groupUser(u1);
        Set u2 = downLevelAllUser(u1);
        Map> m2 = groupUser(u2);
        Set u3 = downLevelAllUser(u2);
        Map> m3 = groupUser(u3);
        Set u4 = downLevelAllUser(u3);
        Map> m4 = groupUser(u4);
        Set u5 = downLevelAllUser(u4);
        Map> m5 = groupUser(u5);
        Set u6 = downLevelAllUser(u5);
        Map> m6 = groupUser(u6);
        Set u7 = downLevelAllUser(u6);
        Map> m7 = groupUser(u7);
        Set u8 = downLevelAllUser(u7);
        Map> m8 = groupUser(u8);
        return Arrays.asList(m1, m2, m3, m4, m5, m6, m7, m8).parallelStream().map(m -> {
            Map newMap = new HashMap<>();
            m.forEach((k, v) -> newMap.put(k, v.size()));
            return newMap;
        }).collect(Collectors.toList());
    }

优化结果:
总用户数为:120W
计算机器:I5 六代 8G内存
时间:4秒

好了,优化完毕了,大神们还有什么高招,欢迎来指导!!!!!!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65930.html

相关文章

发表评论

0条评论

最新活动
阅读需要支付1元查看
<