MySQL 查询问题求教 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
lyusantu
V2EX    程序员

MySQL 查询问题求教

  •  
  •   lyusantu 2019-01-18 18:11:21 +08:00 3135 次点击
    这是一个创建于 2470 天前的主题,其中的信息可能已经有所发展或是发生改变。
    查询一个商家列表,同时每个商家又返回自己店铺销量最高的三条数据

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

    你这完全反过来……
    rockyou12
        22
    rockyou12  
       2019-01-18 20:51:25 +08:00
    搞个定时任务,分批次扫所有店铺把结构缓存下。你真业务量很大有要实时本来就不太可能,要准实时肯定只有把统计数据扔到其他专门的 OLAP 平台。不过还有个可能是 lz 忘了加索引或者数据没分页……
    rockyou12
        23
    rockyou12  
       2019-01-18 20:53:52 +08:00
    还有类似 kafka stream 这样的流计算也是很好的解决方案
    nanmu42
        24
    nanmu42  
       2019-01-19 00:00:56 +08:00 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;

    由于不清楚你具体的数据结构,只能算抛砖引玉了。
    ChaselPansy
        26
    ChaselPansy  
       2019-01-19 00:09:19 +08:00
    开三个销量最高字段,定时离线计算,比如每晚算好。
    msg7086
        27
    msg7086  
       2019-01-19 03:21:02 +08:00
    可以 defer 的话 defer 到 cron 里执行。
    要当场跑的话 N+1。
    强行做复杂查询可以找 Oracle 看看有没有解决方案。
    gz911122
        28
    gz911122  
       2019-01-19 19:59:12 +08:00
    mysql 8.0 使用窗口函数
    usdf
        29
    usdf  
       2019-01-21 10:24:05 +08:00
    @wysnylc #17 楼说说他的 sql 查询时间长我让他看别人类似的 sql 写法 这完全没毛病,你怎么就知道楼主写的 sql 没问题呢,先知? 至于你的素质也是呵呵就可以形容的了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2660 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 14:54 PVG 22:54 LAX 07:54 JFK 10:54
    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