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

342 天前
 dyv9

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

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

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

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

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

2260 次点击
所在节点    程序员
24 条回复
3a10IgjVYjvsH93b
342 天前
考虑影响价格的因素? 比如:重量越大折扣越少 => 重量和价格成正比,重量的顺序就是价格的顺序?我能想到的, 不知道有没有用.......

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

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


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

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

所以,凑活弄弄就行了 :P
dyv9
341 天前
@AX5N 网页客户端,还要支持小程序和手机等,没法让客户端处理数据
Ginz
341 天前
标记
neoblackcap
341 天前
实际上这个就是搜索引擎的需求,你在做排名相关工作。
我的建议是,后台有服务不断根据需求更新索引。然后用户实际搜索的时候,就可以通过索引快速查询到商品

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1009851

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX