请教商品价格排序的性能问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
dyv9
V2EX    程序员

请教商品价格排序的性能问题

  •  
  •   dyv9 2024-01-19 00:58:16 +08:00 2763 次点击
    这是一个创建于 683 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近碰到一个业务排序要求,多家供应商提供相似的商品 但可能折扣不一样,折扣也至少有 2 种,一个是当前供应商的通用折扣作用于它的所有商品,还有另一种比如不同重量区间(重量越大折扣越少,甚至加价)设置不同的折扣,比如商品重量在 20 - 30 重量单位的 9 折,40 - 50 重量单位之间的 95 折,300 以上的 重量单位的可能是加价 15%。

    现在搜索时符合条件的数据要按折后价排序后分页显示。

    这个查询本身还有 7 ,8 个 过滤条件可选,比如颜色,形状等。 商品不会频繁修改,可以多加些索引。老板还说客户可以不输入任何限制条件。商品的规模 暂时估计 总共 1 千万,一个供应商的商品估计不超过 50 万。

    因为要实时计算价格再排序的话,会影响性能,那个重量范围还要联表查询得到区间折扣率,所有数据 MySQL 要立即先计算一次才能比较价格,换个思路,如果事先把价格转换成折后价 避免查询时临时计算价格,如果供应商级别修改了折扣率,最多的可能有几十万个商品都要受影响,在后台换算成折后价的话,会有生效的延迟,全部更新完之前客户查询时排序结果就不正确。

    大家说说,这个怎么处理比较好。

    24 条回复    2024-01-21 12:18:47 +08:00
    3a10IgjVYjvsH93b
        1
    3a10IgjVYjvsH93b  
       2024-01-19 02:16:16 +08:00
    考虑影响价格的因素? 比如:重量越大折扣越少 => 重量和价格成正比,重量的顺序就是价格的顺序?我能想到的, 不知道有没有用.......

    感觉 实时计算 比 存储临时价格 更合理, 前者是快慢问题,后者是逻辑问题。

    考虑 价格顺序对使用者的重要性 和 响应快慢对使用者的重要性 ?


    我看到这段文字的一些零散想法....... hhh
    3a10IgjVYjvsH93b
        2
    3a10IgjVYjvsH93b  
       2024-01-19 02:17:49 +08:00
    折扣是否经常变动.......
    AX5N
        3
    AX5N  
       2024-01-19 03:50:34 +08:00
    系统对内对外?
    一个供应商超过 50 万,但一个商品应该没有 50 万个供应商吧。如果一次展示的搜索结果不多,也不怕数据被人抓取的话,直接把数据全扔给客户端,让客户端自己算去。
    xuanbg
        4
    xuanbg  
       2024-01-19 06:36:56 +08:00
    存折后价
    dyv9
        5
    dyv9  
    OP
       2024-01-19 07:28:57 +08:00 via Android
    @einvcz 变更少。可能 1 天 或 几天更新一次。供应商数量不算多,几百家的样子。
    dyv9
        6
    dyv9  
    OP
       2024-01-19 07:31:01 +08:00 via Android
    @AX5N 可能几百家供应商。一个商品可能只有 3 - 5 个供应商卖,但相似的商品有蛮多供应商卖。
    dyv9
        7
    dyv9  
    OP
       2024-01-19 07:38:08 +08:00 via Android
    @einvcz 大致是这规则,但每家原价不同折扣率可能也不同,所以一家供应商的按原价和重量比较也是大致相同的排序结果,但 不同供应商一起来比较就要计算后才知道。 现在的程序是查询时让 SQL 计算排序,但感觉比较慢。
    litchinn
        8
    litchinn  
       2024-01-19 09:04:46 +08:00
    从业务入手,看能不能提前制定折扣计划,比如 1 号之前配置 1-3 号的折扣,这样有充足的时间去计算折后价。
    如果非要实时调整,那除了变动后计算,通过分组并发建结果表等常规方式计算没啥办法,你肯定不能每次查询再去计算的
    xiaoHuaJia
        9
    xiaoHuaJia  
       2024-01-19 09:23:39 +08:00
    先算好存在另一张这算表中,在监听供应商改折扣在重新计算相关的商品,有一定的延迟,但也不会很大。如果实时算性能挺不住
    NelsonZhao
        10
    NelsonZhao  
       2024-01-19 09:38:45 +08:00
    可以考虑做结果表保存折后价,用 canal 监听折扣表,有变动就更新一下结果表
    pxcking
        11
    pxcking  
       2024-01-19 09:46:56 +08:00
    我们公司很简单,把这种和价格相关的数据全部放到 redis 里,根本不走 mysql
    AutumnVerse
        12
    AutumnVerse  
       2024-01-19 10:13:38 +08:00 via Android
    我们业务比你们更加复杂,我们的价格在不同人,不同时间,不同供应商,不同细项,价格全部不一样。当多个日期或者类型选择时需要以平局价格过滤排序,我们目前数据量 100 亿+

    查询接口 QPS 100 左右,我们用的 StarRocks 。这里同样好奇,这种涉及数据规模大,计算复杂的查询逻辑其他公司是怎么做的
    AutumnVerse
        13
    AutumnVerse  
       2024-01-19 10:17:07 +08:00
    用 SQL 表述查询逻辑大概是这样的:

    Select product_id, avg(price) as avg_price
    from sku_table
    where time > xxx
    and time < xxx
    and xxxxxx
    group by product_id
    having avg_price > xxx
    and avg_price < xxx
    order by avg_price
    boobo
        14
    boobo  
       2024-01-19 10:53:11 +08:00
    留个标记,求教大佬
    9136347
        15
    9136347  
       2024-01-19 10:59:26 +08:00
    如果事先计算,把不同情况下的结果存到数据库里面去。需要考虑的就是存储的数据量的量级和读取效率问题。同事这种结构的数据,不管是 redis ,mongo ,还是 es 都有办法解决。但是如果是实时计算的话,对计算的要求会比较高,扩展起来复杂。
    fengpan567
        16
    fengpan567  
       2024-01-19 12:00:13 +08:00
    是商品总数量 1000W 还是 skuid1000 万?感觉一个供应商最多也就几百件商品吧,放到 redis 里排序就行
    tramm
        17
    tramm  
       2024-01-19 12:17:42 +08:00
    TB 你按价格排序, 它也不是按价格排序的

    所以,凑活弄弄就行了 :P
    dyv9
        18
    dyv9  
    OP
       2024-01-19 12:45:50 +08:00 via Android
    @AX5N 网页客户端,还要支持小程序和手机等,没法让客户端处理数据
    Ginz
        19
    Ginz  
       2024-01-19 16:34:16 +08:00
    标记
    neoblackcap
        20
    neoblackcap  
       2024-01-19 23:56:35 +08:00
    实际上这个就是搜索引擎的需求,你在做排名相关工作。
    我的建议是,后台有服务不断根据需求更新索引。然后用户实际搜索的时候,就可以通过索引快速查询到商品
    XxxxD
        21
    XxxxD  
       2024-01-20 11:41:33 +08:00
    不是很熟悉实际场景,个人想法是:
    先全部产品原价排序,在这基础上,按除否有店铺折扣排序,有店铺折扣的往前(有店铺折扣肯定是更省钱的吧),再在这基础上,再次按照重量排序,如果全部供应商对于重量的折扣是差不多的,找出折扣为 0 的重量区间,低于这个重量的就是有减价,往前,高于这个重量的加价,分别把这两个重量区间放在第二次排序的前和后

    不知道有没有说清楚
    chenxiankong
        22
    chenxiankong  
       2024-01-20 13:33:47 +08:00
    建议监听 binlog ,异构数据到 es
    dyv9
        23
    dyv9  
    OP
       2024-01-21 12:18:02 +08:00 via Android
    @chenxiankong es 擅长多栏位组合查询吗? 10 位过滤,多数是枚举值(多选),另有可选的 2 个范围查询(比如重量范围)。
    dyv9
        24
    dyv9  
    OP
       2024-01-21 12:18:47 +08:00 via Android
    @dyv9 12 个过滤条件
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5146 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 01:18 PVG 09:18 LAX 17:18 JFK 20:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86