一个 SQL 大家帮忙理解一下

2019-07-18 20:36:25 +08:00
 huzhengnan

优化老项目,访问人数不多,数据库 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. 这么写的思路是什么
4604 次点击
所在节点    MySQL
15 条回复
oaix
2019-07-18 20:52:23 +08:00
SELECT a.*
FROM user a
WHERE a.seller_id = 600000
ORDER BY user_type DESC LIMIT 1
shanYueFengCheng
2019-07-18 20:57:59 +08:00
复杂 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
2019-07-18 20:58:02 +08:00
@oaix 楼上正解。查询某个 seller_id 中 user_type 最大的一行。那个子查询没必要。
shanYueFengCheng
2019-07-18 21:01:54 +08:00
不确定原表设计,不能确定只有一条
taogen
2019-07-18 21:05:39 +08:00
@shanYueFengCheng 老哥说得对,在下疏忽了。一楼的回答不一定对,要看业务是不是只需要一条数据。
oaix
2019-07-18 21:08:15 +08:00
@taogen 看最后面有个 group by
jaskle
2019-07-18 21:23:51 +08:00
无索引的 group by 是锁表利器
taogen
2019-07-18 21:37:42 +08:00
@oaix 最后的 group by 没看懂,感觉没什么意义,父查询并不需要使用分组对应的函数如 max,min。
你的 limit 1 感觉不行,如果有多行数据的 user_type = max(user_type) 呢?原结果是多行,你的始终是一行
txwd
2019-07-18 21:53:19 +08:00
据我所知,这个 SQL 执行不了,最后来这个 GROUP BY。代码没贴全?
akira
2019-07-18 21:56:15 +08:00
1l 应该就对了. 除非 a 表里面有 usertype 是大于 b 表里面的。

原 sql 应该也没有太大问题,怀疑 seller_id 没做索引
oaix
2019-07-18 21:57:14 +08:00
@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
2019-07-18 22:04:02 +08:00
@oaix group by 还有这个效果。多谢赐教!
zjp
2019-07-18 22:31:30 +08:00
@oaix 有 ONLY_FULL_GROUP_BY 的问题
+----+------+------+
| id | type | name |
+----+------+------+
| 3 | 2 | c |
| 4 | 2 | d |
+----+------+------+
都满足条件,但是 group by 丢弃了一行
LeeSeoung
2019-07-19 10:19:48 +08:00
先查 sql 执行时间,找出慢的再优化,不要凭人为感觉哪个 sql 有问题,找到执行慢的 sql 直接看执行计划来进行优化。
addsionhuey
2019-07-19 10:56:00 +08:00
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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/584228

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX