V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dyv9
V2EX  ›  程序员

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

  •  
  •   dyv9 · 88 天前 · 1915 次点击
    这是一个创建于 88 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

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

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


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

    查询接口 QPS 100 左右,我们用的 StarRocks 。这里同样好奇,这种涉及数据规模大,计算复杂的查询逻辑其他公司是怎么做的
    jiangwei2222
        13
    jiangwei2222  
       87 天前
    用 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  
       87 天前
    留个标记,求教大佬
    9136347
        15
    9136347  
       87 天前
    如果事先计算,把不同情况下的结果存到数据库里面去。需要考虑的就是存储的数据量的量级和读取效率问题。同事这种结构的数据,不管是 redis ,mongo ,还是 es 都有办法解决。但是如果是实时计算的话,对计算的要求会比较高,扩展起来复杂。
    fengpan567
        16
    fengpan567  
       87 天前
    是商品总数量 1000W 还是 skuid1000 万?感觉一个供应商最多也就几百件商品吧,放到 redis 里排序就行
    tramm
        17
    tramm  
       87 天前
    TB 你按价格排序, 它也不是按价格排序的

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

    不知道有没有说清楚
    chenxiankong
        22
    chenxiankong  
       86 天前
    建议监听 binlog ,异构数据到 es
    dyv9
        23
    dyv9  
    OP
       85 天前 via Android
    @chenxiankong es 擅长多栏位组合查询吗? 10 位过滤,多数是枚举值(多选),另有可选的 2 个范围查询(比如重量范围)。
    dyv9
        24
    dyv9  
    OP
       85 天前 via Android
    @dyv9 12 个过滤条件
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   998 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:18 · PVG 06:18 · LAX 15:18 · JFK 18:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.