有这样一个场景,我有一张商家表,一个商品表,和一个商家货架表,根据门店距离升序,商品销量降序,商品价格升降序

门店信息表

有这样一个场景,我有一张商家表,一个商品表,和一个商家货架表,根据门店距离升序,商品销量降序,商品价格升降序

距离排序需要用到 lat 和 lng 字段
门店有对应的货架数据,货架数据主要记录商品
货架表
有这样一个场景,我有一张商家表,一个商品表,和一个商家货架表,根据门店距离升序,商品销量降序,商品价格升降序

商品表

有这样一个场景,我有一张商家表,一个商品表,和一个商家货架表,根据门店距离升序,商品销量降序,商品价格升降序

前端查询数据有分页,每次查询数据我基本都是把全部门店信息查出来,然后循环,在查询对应的货架表在连表差商品表,然后获取销量最高的那一条商品信息。
这种方式导致,如果商品数据过多会导致接口响应时间会比较长,之前测试数据商品表300+数据接口响应大概在3s-5s左右

以下是对应接口代码代码

有这样一个场景,我有一张商家表,一个商品表,和一个商家货架表,根据门店距离升序,商品销量降序,商品价格升降序

有这样一个场景,我有一张商家表,一个商品表,和一个商家货架表,根据门店距离升序,商品销量降序,商品价格升降序

最后返回商品信息和对应门店信息在分页,以下是返回后的后续代码
其中 getGoodsUnavailableTime 获取商品的不可用时间,又查了一次数据库,当然这个就比较快。
getMerchants 获取商品对应的适用门店,也是查了数据库,然后里面又去查了门店的评价统计数量和门店评分

有这样一个场景,我有一张商家表,一个商品表,和一个商家货架表,根据门店距离升序,商品销量降序,商品价格升降序

感觉如果商品数据在多点的话,查询数据库会把程序拖死,如果在来点并发就更容易噶了,想看看有没有什么好点的解决办法可以解决查询慢的问题,主要是解决慢的问题

页面展示图

有这样一个场景,我有一张商家表,一个商品表,和一个商家货架表,根据门店距离升序,商品销量降序,商品价格升降序

猪猪
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 65

不太了解商家的量级,如果量级不大可以这么来:

  1. 根据用户距离排序从数据库取出所有商家id,做出有序的商家集合:ids[]
  2. 根据ids[]取出所有的商品数据
  3. 把商品数据在内存里根据ids[]排序,组装,返回
2个月前 评论
猪猪 (楼主) 2个月前
猪猪 (楼主) 2个月前

你最好先确认哪个sql或者哪部分逻辑处理耗时长,不太清楚你的具体业务逻辑,第一个问题是前端分页获取为什么要把所有都查出来,再有一些商品数据在这个列表要不要展示是否可以去除查询,还有就是一些像你说的销量最高这种,研究下要不要每次都查,字段维护可不可以

2个月前 评论
猪猪 (楼主) 2个月前
猪猪 (楼主) 2个月前

既然已经数组切割了进行分页返回商品信息,最后一张图的SQL应该可以提到循环前,用in查询组装之后直接再循环里面isset判断来赋值处理

2个月前 评论
猪猪 (楼主) 2个月前
小猪蹄子 (作者) 2个月前
猪猪 (楼主) 2个月前
小猪蹄子 (作者) 2个月前
猪猪 (楼主) 2个月前
小猪蹄子 (作者) 2个月前
猪猪 (楼主) 2个月前

初看一下《距离排序》那块,感觉有些问题啊:

  1. 好像没必要,一次性算出50km内商家,的所有商品,的销量?

    能不能根据上次分页(如[0km, 1km)的最远商家(如800m

    继续找下一段距离的(如[800m, 2km)商家列表,再算这批商家的销冠商品?

  2. 货架表的索引,改成site_id, show, status, goods_id,应该能快些。

    因为不用每次都回表查statusgoods_id

    另外,statusshow能不能合并呢。。

  3. 为啥你是,按价格从高到低排,价格相同再看销量呢。。

  4. 另外,你不是取最高一条吗?怎么不数据库里排好,直接拿出来呢?

    如果平均每家店有 100 个商品,你数据传输量就少 99% 啊。。

  5. 如果你商品表已经有《是否上架了》信息,为啥还要连货架表呢。。

    是因为只有货架表有《是否展示》数据吗?

    那就像第二点说的:

    statusshow能不能合并呢。。

  6. 后面没细看,只看了文字。

    获取商品的不可用时间,又查了一次数据库

    能不能在取销冠商品时,顺便也拿了呢?

    又去查了门店的评价统计数量和门店评分

    同理,能不能在取商家时,顺便也拿了呢。。

2个月前 评论
猪猪 (楼主) 2个月前
wxf666 (作者) 2个月前
猪猪 (楼主) 2个月前
猪猪 (楼主) 2个月前

商家对门店的距离是固定的,就算地址有变化可以更新,完全用一个字段或者关联表做距离数据保存。同理,销量一样可以做单独字段,不用实时去查。距离的类别,可以做距离分组来筛选,比如0到80M是一个组,80到150时一组。

2个月前 评论
小猪蹄子 2个月前
猪猪 (楼主) 2个月前
keyboby (作者) 2个月前
keyboby (作者) 2个月前
keyboby (作者) 2个月前
猪猪 (楼主) 2个月前
keyboby (作者) 2个月前
猪猪 (楼主) 2个月前
猪猪 (楼主) 2个月前
keyboby (作者) 2个月前

可以尝试用geohash来存储位置信息,查询的时候先查询对应geohash的范围的数据,可以减少你得分页数据量,在考虑你的连表查询的索引建立,看见你得代码有好多部分可以提出来公用,同样的连表只是排序方式不同这些可以提出来,代码更加简洁

2个月前 评论
猪猪 (楼主) 2个月前
猪猪 (楼主) 2个月前
feixiangdeshou (作者) 2个月前

查商家和用户的距离可以用MySQL的ST_Distance_Sphere函数,就不需要查出所有的商家再计算距离

2个月前 评论
猪猪 (楼主) 2个月前
wxf666 2个月前

前端页面操作做修改,先请求返回门店列表,根据门店id在返回货架,同理再返回货物。。。。。

2个月前 评论
猪猪 (楼主) 2个月前
DogLoML

如果商品只属于一个商家,并且50km内的商家数量不是很多,可以把商家id存到商品表,sql查出按距离排序并筛选过的商家ids,假如ids=[3,2,1,5],商家不多的话不会很慢,然后商品表WHERE 商家id in (3,2,1,5) ORDER BY FIELD(商家id, 3,2,1,5)

2个月前 评论
猪猪 (楼主) 2个月前
DogLoML (作者) 2个月前
猪猪 (楼主) 2个月前
猪猪 (楼主) 2个月前
DogLoML (作者) 2个月前
猪猪 (楼主) 2个月前

这种查询本来都有问题,应该将商家的经纬度数据放到商品表上,或者商品表为主表left join 商家 先根据经纬度算距离排序,在根据商品销量(每次购买商品对商品进行记录)排序,在根据价格排序 其次如果用户登录了在加个缓存

2个月前 评论
猪猪 (楼主) 2个月前
Awx (作者) 2个月前
猪猪 (楼主) 2个月前
Awx (作者) 2个月前
Awx (作者) 2个月前
猪猪 (楼主) 2个月前

用搜索引擎可能更好点,如果数据没多少不需要搜索引擎,可以尝试把数据拉平; 新建一张搜索表,保存纬度、商品销量、价格等数据,用来搜索; 这样只需要一条sql就行了,查出来的数据再把需要的数据给拼上

2个月前 评论
猪猪 (楼主) 2个月前
rayken (作者) 2个月前
猪猪 (楼主) 2个月前

我们是这么干的,数据不多的话可以试

file

#距离单位是km
round(ST_Distance_Sphere (point (lon, lat),point($userLon,$userLat) ) / 1000,2) as distance
2个月前 评论
猪猪 (楼主) 2个月前

这里 N+1 了,肯定慢,你300个商品,这块就执行了300次查询 file

2个月前 评论
猪猪 (楼主) 2个月前
  1. 使用搜索引擎(elasticsearch 或者 meilisearch)
  2. 稍微改造一下数据库,产品表增加 GeoHash 字段。

个人推荐使用搜索引擎,后续扩展性高一些。

2个月前 评论

看看遍历里的查询能不能提到循环外一次性查结果,后面再组装数据

1个月前 评论

建张新的表,将所有要查询和排序的条件都加上;

1个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!