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

MySQL 查询问题求教

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

    商家 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
    littleylv
        1
    littleylv  
       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。
    littleylv
        9
    littleylv  
       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 方式查询问题不大。
    Tomorrowxxy
        12
    Tomorrowxxy  
       2019-01-18 18:55:42 +08:00
    @all v2 的人都不刷 leetcode 的吗
    Tomorrowxxy
        13
    Tomorrowxxy  
       2019-01-18 18:57:12 +08:00
    @lyusantu 关键字 : 部门工资前三高的员工 这里有你想要的
    wysnylc
        14
    wysnylc  
       2019-01-18 19:00:52 +08:00
    @Tomorrowxxy #13 笑出声,人家问的是怎么优化查询时间不是怎么查出前三,别把人家当白痴最终只能是自己当白痴
    Tomorrowxxy
        15
    Tomorrowxxy  
       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  
       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 使用窗口函数
    Tomorrowxxy
        29
    Tomorrowxxy  
       2019-01-21 10:24:05 +08:00
    @wysnylc #17 楼说说他的 sql 查询时间长我让他看别人类似的 sql 写法 这完全没毛病,你怎么就知道楼主写的 sql 没问题呢,先知? 至于你的素质也是呵呵就可以形容的了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2898 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:25 · PVG 22:25 · LAX 06:25 · JFK 09:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.