优化老项目,访问人数不多,数据库 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
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 |
2
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 |
3
taogen 2019-07-18 20:58:02 +08:00 via Android
@oaix 楼上正解。查询某个 seller_id 中 user_type 最大的一行。那个子查询没必要。
|
4
shanYueFengCheng 2019-07-18 21:01:54 +08:00
不确定原表设计,不能确定只有一条
|
5
taogen 2019-07-18 21:05:39 +08:00 via Android
@shanYueFengCheng 老哥说得对,在下疏忽了。一楼的回答不一定对,要看业务是不是只需要一条数据。
|
7
jaskle 2019-07-18 21:23:51 +08:00 via Android
无索引的 group by 是锁表利器
|
8
taogen 2019-07-18 21:37:42 +08:00 via Android
@oaix 最后的 group by 没看懂,感觉没什么意义,父查询并不需要使用分组对应的函数如 max,min。
你的 limit 1 感觉不行,如果有多行数据的 user_type = max(user_type) 呢?原结果是多行,你的始终是一行 |
9
txwd 2019-07-18 21:53:19 +08:00
据我所知,这个 SQL 执行不了,最后来这个 GROUP BY。代码没贴全?
|
10
akira 2019-07-18 21:56:15 +08:00
1l 应该就对了. 除非 a 表里面有 usertype 是大于 b 表里面的。
原 sql 应该也没有太大问题,怀疑 seller_id 没做索引 |
11
oaix 2019-07-18 21:57:14 +08:00 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) |
13
zjp 2019-07-18 22:31:30 +08:00 1
@oaix 有 ONLY_FULL_GROUP_BY 的问题
+----+------+------+ | id | type | name | +----+------+------+ | 3 | 2 | c | | 4 | 2 | d | +----+------+------+ 都满足条件,但是 group by 丢弃了一行 |
14
LeeSeoung 2019-07-19 10:19:48 +08:00
先查 sql 执行时间,找出慢的再优化,不要凭人为感觉哪个 sql 有问题,找到执行慢的 sql 直接看执行计划来进行优化。
|
15
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 |