bfchengnuo / MyRecord

平时充电做的笔记,一个程序猿的自我修养.
https://bfchengnuo.com/MyRecord/
33 stars 8 forks source link

Mysql执行FIND_IN_SET慢 #47

Closed bfchengnuo closed 4 years ago

bfchengnuo commented 4 years ago

示例 SQL:

SELECT cardName
FROM diyCard
WHERE FIND_IN_SET(id, ( SELECT group_concat(id) FROM card))

当然可以加索引,但这并不是问题的关键,根据 SQL 的执行顺序,where 中的子查询要被执行 N 次,但这是不必要的。

修改后:

SELECT cardname
FROM diycard, ( SELECT group_concat(id) id FROM card) temp
WHERE
FIND_IN_SET(id, temp.card)

(select group_concat(id) from card) 加到 from 后面,执行 sql 时直接组装数据源。还有这里的 group_concat(id) 让这个数据源只有一条记录,所以不会产生笛卡尔集

当然,优化不止这一种,多使用 explain 分析查询语句。

参考:https://www.cnblogs.com/Tinsv/p/8316833.html

bfchengnuo commented 4 years ago

GROUP_CONCAT(expr) 函数会从 expr 中连接所有非 NULL 的字符串。如果没有非 NULL 的字符串,那么它就会返回 NULL。

以逗号最为默认的连接字符,可使用 SEPARATOR 指定分隔符,默认 1024 后会被截断; 64 位版本不支持最大值 18446744073709551615 SET SESSION group_concat_max_len=18446744073709551615;