• 请不要在回答技术问题时复制粘贴 AI 生成的内容
LoremIpSum
V2EX  ›  程序员

需求:统计用户首次 XXX 的时间,用户表:百万数据, XXX 表:亿级数据

  •  
  •   LoremIpSum · Sep 30, 2019 · 4322 views
    This topic created in 2428 days ago, the information mentioned may be changed or developed.

    来了几个比较不好处理的需求: 统计用户首次 XXX 的时间,XXX 代表用户行为,可以是评论,发帖,点赞等,XXX 表的数据上亿,用户表也接近百万,直接用 SQL 去查肯定不是很合适,如果要把每个用户首次 XXX 的数据拿出来的话,大概怎么样来跑数据比较合适?

    24 replies    2019-09-30 22:14:20 +08:00
    F281M6Dh8DXpD1g2
        1
    F281M6Dh8DXpD1g2  
       Sep 30, 2019
    为啥直接写 sql 不合适?
    alamaya
        2
    alamaya  
       Sep 30, 2019
    没戏,拆表,把用户行为细分,存量数据迁移,只记录最新行为时间
    LoremIpSum
        3
    LoremIpSum  
    OP
       Sep 30, 2019
    @liprais

    ```
    SELECT MIN(A.CreateTime) ,A.UserId
    FROM XXX A
    GROUP BY A.UserId
    ```
    大概是这种 SQL,跑起来特别慢
    encro
        4
    encro  
       Sep 30, 2019
    stat_by_day:
    date,
    action,
    value
    sadfQED2
        5
    sadfQED2  
       Sep 30, 2019
    分表 or 加缓存

    你用 uid 分表不就完事了吗
    arrow8899
        6
    arrow8899  
       Sep 30, 2019
    SELECT * FROM (SELECT * FROM actives ORDER BY add_time ASC ) t1 GROUP BY t1.uid, t1.active_name;
    Raymon111111
        7
    Raymon111111  
       Sep 30, 2019
    加上 user_id, action_type, time 的联合索引之后

    直接查就行了, limit 1 很快的
    misaka19000
        8
    misaka19000  
       Sep 30, 2019
    每天凌晨算一次不就行了
    seaguest
        9
    seaguest  
       Sep 30, 2019
    直接代码去实现吧,把用户都分页查出来,然后查每个用户的第一条,控制好并发,也很快的。
    misaka19000
        10
    misaka19000  
       Sep 30, 2019
    这种数据都是确定的,每天针对最新数据算一次就可以了,感觉没啥难度
    ccoming
        11
    ccoming  
       Sep 30, 2019
    是“首次”,不是最新?
    LoremIpSum
        12
    LoremIpSum  
    OP
       Sep 30, 2019
    @ccoming 首次!
    jieee
        13
    jieee  
       Sep 30, 2019
    单独维护一张表
    tanszhe
        14
    tanszhe  
       Sep 30, 2019
    就用 3 楼的写法 ,
    把首次 xxx 的数据存到时序数据库
    什么都不用优化 百亿也很快
    xio
        15
    xio  
       Sep 30, 2019
    postgres left join lateral
    opengps
        16
    opengps  
       Sep 30, 2019
    看到这类帖子我就想总结下: https://www.opengps.cn/Blog/View.aspx?id=470&from=v2ex
    msg7086
        17
    msg7086  
       Sep 30, 2019
    首次多简单,直接写代码扫全表啊,数据放在 redis 之类的地方。程序每次记录扫完的数据,从头开始一页一页扫。(比如每页 10 万条记录。)扫到以后去 redis 检查是否首次,是的话写下时间,不是的话跳过。
    应该很快的。
    passerbytiny
        18
    passerbytiny  
       Sep 30, 2019
    最省心(但最废功夫)的办法是,搞数据仓库或 BI。最省功夫(但要一直重复造轮子)的方法是,写一个专门的程序,把数据从基础表抽取到中间表。最不可能的方式是,写一个超牛逼的 SQL 查出来。
    Soar360
        19
    Soar360  
       Sep 30, 2019
    按行去处理咯。
    vmskipper
        20
    vmskipper  
       Sep 30, 2019
    这个好像微博的面试题。。。。
    dog82
        21
    dog82  
       Sep 30, 2019
    这种需求不难,把“首次 xxx”记录单独记录一张表就行
    veike
        22
    veike  
       Sep 30, 2019 via Android
    注册之后首次吗?接近百万用户也不多啊,加个用户附表
    gamexg
        23
    gamexg  
       Sep 30, 2019
    联合索引,
    查询没什么问题,就是如果各种索引太多会影响插入速度。
    pinews
        24
    pinews  
       Sep 30, 2019
    16M 内存的服务器和 16G 的服务器速度的确不一样,上云数据库试试,没有不合适。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2846 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 98ms · UTC 06:18 · PVG 14:18 · LAX 23:18 · JFK 02:18
    ♥ Do have faith in what you're doing.