首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
huzhengnan
V2EX  ›  MySQL

一个 SQL 大家帮忙理解一下

  •  1
     
  •   huzhengnan · 185 天前 · 2620 次点击
    这是一个创建于 185 天前的主题,其中的信息可能已经有所发展或是发生改变。

    优化老项目,访问人数不多,数据库 CPU100%,内存 100% 发现 filter 中有这么个 SQL,也不止这么个 SQL,但是这个是我看了比较久的一个

    SELECT a.*
    FROM user a
    WHERE a.seller_id = 600000
    	AND a.user_type = (
    		SELECT MAX(b.user_type)
    		FROM user b
    		WHERE a.seller_id = b.seller_id
    		GROUP BY seller_id
    	)
    GROUP BY seller_id
    

    问两个问题

    1. 可以改为什么 SQL
    2. 这么写的思路是什么
    15 回复  |  直到 2019-07-19 10:56:00 +08:00
    oaix
        1
    oaix   185 天前
    SELECT a.*
    FROM user a
    WHERE a.seller_id = 600000
    ORDER BY user_type DESC LIMIT 1
    shanYueFengCheng
        2
    shanYueFengCheng   185 天前
    复杂 SQL 分为多次简单查询----《深入理解 Mysql 》

    拆分成两次查询。
    目标表 user 取个用户类型的最大值
    SELECT MAX(user_type) FROM user

    获取用户类型的最大值,userType 和销售者 id sellerId
    SELECT a.* FROM user a WHERE a.seller_id = ? AND a.user_type = ?
    GROUP BY seller_id
    taogen
        3
    taogen   185 天前 via Android
    @oaix 楼上正解。查询某个 seller_id 中 user_type 最大的一行。那个子查询没必要。
    shanYueFengCheng
        4
    shanYueFengCheng   185 天前
    不确定原表设计,不能确定只有一条
    taogen
        5
    taogen   185 天前 via Android
    @shanYueFengCheng 老哥说得对,在下疏忽了。一楼的回答不一定对,要看业务是不是只需要一条数据。
    oaix
        6
    oaix   185 天前
    @taogen 看最后面有个 group by
    jaskle
        7
    jaskle   185 天前 via Android
    无索引的 group by 是锁表利器
    taogen
        8
    taogen   184 天前 via Android
    @oaix 最后的 group by 没看懂,感觉没什么意义,父查询并不需要使用分组对应的函数如 max,min。
    你的 limit 1 感觉不行,如果有多行数据的 user_type = max(user_type) 呢?原结果是多行,你的始终是一行
    txwd
        9
    txwd   184 天前
    据我所知,这个 SQL 执行不了,最后来这个 GROUP BY。代码没贴全?
    akira
        10
    akira   184 天前
    1l 应该就对了. 除非 a 表里面有 usertype 是大于 b 表里面的。

    原 sql 应该也没有太大问题,怀疑 seller_id 没做索引
    oaix
        11
    oaix   184 天前   ♥ 2
    @taogen #8

    mysql-sql> select * from tbl_test;
    +----+------+------+
    | id | type | name |
    +----+------+------+
    | 1 | 1 | a |
    | 2 | 1 | b |
    | 3 | 2 | c |
    | 4 | 2 | d |
    +----+------+------+
    4 rows in set (0.00 sec)
    mysql-sql> select * from tbl_test where type=2;
    +----+------+------+
    | id | type | name |
    +----+------+------+
    | 3 | 2 | c |
    | 4 | 2 | d |
    +----+------+------+
    2 rows in set (0.00 sec)
    mysql-sql> select * from tbl_test where type=2 group by type;
    +----+------+------+
    | id | type | name |
    +----+------+------+
    | 3 | 2 | c |
    +----+------+------+
    1 row in set (0.00 sec)
    taogen
        12
    taogen   184 天前 via Android
    @oaix group by 还有这个效果。多谢赐教!
    zjp
        13
    zjp   184 天前   ♥ 1
    @oaix 有 ONLY_FULL_GROUP_BY 的问题
    +----+------+------+
    | id | type | name |
    +----+------+------+
    | 3 | 2 | c |
    | 4 | 2 | d |
    +----+------+------+
    都满足条件,但是 group by 丢弃了一行
    LeeSeoung
        14
    LeeSeoung   184 天前
    先查 sql 执行时间,找出慢的再优化,不要凭人为感觉哪个 sql 有问题,找到执行慢的 sql 直接看执行计划来进行优化。
    addsionhuey
        15
    addsionhuey   184 天前
    select *
    from (
    SELECT a.*,row_number() over(partition by seller_id order by user_type desc) as ROW_ORDER
    FROM user a
    WHERE a.seller_id = 600000
    )
    where ROW_ORDER = 1
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2526 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 31ms · UTC 13:28 · PVG 21:28 · LAX 05:28 · JFK 08:28
    ♥ Do have faith in what you're doing.