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

MySQL 查询问题求教

  •  
  •   lyusantu · 327 天前 · 1937 次点击
    这是一个创建于 327 天前的主题,其中的信息可能已经有所发展或是发生改变。
    查询一个商家列表,同时每个商家又返回自己店铺销量最高的三条数据

    商家 1 -> 货品 1,货品 2,货品 3
    商家 2 -> 货品 1,货品 2,货品 3
    商家 3 -> 货品 1,货品 2,货品 3

    大佬们在 MySQL 下有什么好的解决方案吗,现在写的 SQL 在数据量大的情况下执行>60s,所以这个要废弃的 SQL 就不拿出来献丑了
    29 回复  |  直到 2019-01-21 10:24:05 +08:00
        1
    littleylv   327 天前
    试试先查商家,再循环商家查商品
        2
    lyusantu   327 天前
    @littleylv 現在就是這樣的
        3
    lyusantu   327 天前
    @littleylv 不希望使用循環,但是沒有什麽特別好的解決方案了
        4
    wysnylc   327 天前
    用程序解决,在数据库解决扩展性维护性极低
        5
    Exialin   327 天前
    MySQL 8.0 后可以用窗口函数。
        6
    Variazioni   327 天前
    复杂查询无谓就是行专列列转行。。外加一堆条件。先写出来最笨的方法之后再优化。。
    如果发现查询时间太长。。
    其实索引和表结构设计的原因更多一点。。
        7
    wysnylc   327 天前
    提供一个思路,查询所有商品中前 10%销量的(加一个限定条件销量必须大于 XX),然后将商品按店家分组就行,数据量小不建议这么做,数据量起来了这样做很方便.
        8
    tiedan   327 天前
    可不可以这样,按照商家 group by,group_concat 前三个货品的 id。
        9
    littleylv   327 天前
    没道理啊,难道你一下查超多商家?
    如果是分页的情况,假设你每次查 20 个商家,循环这 20 个去查商品,应该很快啊?
    explain 一下你的 sql 语句看看用到索引没
        10
    tiedan   327 天前
    当然如果数据量太大 可能会超出 group_concat 的最大长度限制
        11
    yidinghe   327 天前
    如果商家列表本身是分页的话,那么 N+1 方式查询问题不大。
        12
    Tomorrowxxy   327 天前
    @all v2 的人都不刷 leetcode 的吗
        13
    Tomorrowxxy   327 天前
    @lyusantu 关键字 : 部门工资前三高的员工 这里有你想要的
        14
    wysnylc   327 天前
    @Tomorrowxxy #13 笑出声,人家问的是怎么优化查询时间不是怎么查出前三,别把人家当白痴最终只能是自己当白痴
        15
    Tomorrowxxy   327 天前
    @wysnylc #14 优化查询没问题啊 sql 写的有问题借鉴别人执行效率高的 我说错了吗? 你怎么就知道楼主写的就已经是最优解了呢? leetcode 不止教你怎么写 sql 的一个功能
    @lyusantu #2 表索引也记得看下哦
        16
    zppass   327 天前
    这个呢,我有一个思路是做个定时任务之类的更新一个表,表里面的数据存放对应的商家以及销售前三的商品信息。直接查这张表,优点是单表查询本身就够快,优化也简单,缺点是不是实时的,万一突然有个爆款,你设置的定时任务间隔太长,一时反应不出来。
        17
    wysnylc   327 天前
    @Tomorrowxxy #15 "部门工资前三高的员工" 关键字搜出来的就是教怎么写查前三而已,这个根本没有难度不需要查询.
    至于你说的优化你看看你说的: 关键字 : 部门工资前三高的员工 这里有你想要的 .这句话里有任何相关内容和意思?
    说的跟废话一样出来 diss 别人可笑不可笑,刷过两道题就忘了自己是谁
        18
    hanxiV2EX   327 天前 via Android
    用楼上的方法吧,分个数据库出来,不要搞实时的。每个事情分开处理。
        19
    wysnylc   327 天前
    @zppass #16 这个方案是比较好的,牺牲一定的及时性换来性能的提升.数据量大的统计都建议这样做
        20
    mmdsun   327 天前 via Android
    1 查商家列表,程序里多线程查 top3 货物。

    2 这种 SQL 慢吗?建议贴 explain 出来
    select deptno, ename, sal
    from emp e1
    where
    (
    select count(*)
    from emp e2
    where e2.deptno=e1.deptno and e2.sal>=e1.sal
    ) <=3
    order by deptno, sal desc;
        21
    realpg   327 天前
    进数据库全是简单查询才是优化的终极目标

    你这完全反过来……
        22
    rockyou12   327 天前
    搞个定时任务,分批次扫所有店铺把结构缓存下。你真业务量很大有要实时本来就不太可能,要准实时肯定只有把统计数据扔到其他专门的 OLAP 平台。不过还有个可能是 lz 忘了加索引或者数据没分页……
        23
    rockyou12   327 天前
    还有类似 kafka stream 这样的流计算也是很好的解决方案
        24
    nanmu42   327 天前 via Android
    没有写过 MySQL 的窗口函数,PG 里大概是这样,字段我就用中文了:

    with 销量表 as (
    select 商家 id, 货物 id, count(*) as 货物销量
    from 销售流水
    group by 商家 id, 货物 id
    )
    select 商家 id, 货物 id, 货物销量, row_number() over (partition by 商家 id order by 货物销量) as 货物排名
    from 销量表
    having 货物排名 < 4;

    由于不清楚你具体的数据结构,只能算抛砖引玉了。
        26
    ChaselPansy   327 天前
    开三个销量最高字段,定时离线计算,比如每晚算好。
        27
    msg7086   327 天前
    可以 defer 的话 defer 到 cron 里执行。
    要当场跑的话 N+1。
    强行做复杂查询可以找 Oracle 看看有没有解决方案。
        28
    gz911122   326 天前
    mysql 8.0 使用窗口函数
        29
    Tomorrowxxy   324 天前
    @wysnylc #17 楼说说他的 sql 查询时间长我让他看别人类似的 sql 写法 这完全没毛病,你怎么就知道楼主写的 sql 没问题呢,先知? 至于你的素质也是呵呵就可以形容的了
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3926 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 28ms · UTC 01:25 · PVG 09:25 · LAX 17:25 · JFK 20:25
    ♥ Do have faith in what you're doing.