5MMySQL手册中find_in_set函数的语法:
FIND_IN_SET(str,strlist)
str 要查询的字符串
strlist 字段名 参数以”,”分隔 如 (1,2,6,8)
查询字段(strlist)中包含(str)的结果,返回结果为null或记录
假如字符串str在由N个子链组成的字符串列表strlist 中,则返回值的范围在 1 到 N 之间。 一个字符串列表就是一个由一些被 ‘,’ 符号分开的子链组成的字符串。如果第一个参数是一个常数字符串,而第二个是type SET列,则FIND_IN_SET() 函数被优化,使用比特计算。 如果str不在strlist 或strlist 为空字符串,则返回值为 0 。如任意一个参数为NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。
》》生产数据库存在一个问题sql,耗时15s
count( 1 )
FROM
(
SELECT
a.id AS "id",
a.sender_id AS "senderId",
a.sender_name AS "senderName",
a.accept_id AS "acceptId",
a.accept_name AS "acceptName",
a.create_time AS "createTime",
a.remark AS "remark",
a.parent_id AS "parentId",
a.doc_id AS "docId",
a.parent_ids AS "parentIds",
a.source AS "source",
a.STATUS AS "status"
FROM
doc_accept_list a
WHERE
a.parent_id IS NOT NULL
AND find_in_set(
id,
queryAcceptRecordParentsInfo ( '4554a0ed2eab4aa496913efd3fc354a4' ))
) tmp_count
测试发现是因为find_in_set函数导致,该表只有3000多条记录,单单查询queryAcceptRecordParentsInfo ( ‘4554a0ed2eab4aa496913efd3fc354a4’ )函数只需要0.1秒
queryAcceptRecordParentsInfo 函数如下:
```CREATE DEFINER=root@% FUNCTION queryAcceptRecordParentsInfo(rootId varchar(100)) RETURNS varchar(4000) CHARSET utf8
BEGIN
DECLARE fid varchar(2000) default ‘’;
DECLARE str varchar(10000) default rootId;
WHILE rootId is not null do
SET fid =(SELECT parent_id as parentid FROM doc_accept_list WHERE id = rootId);
IF fid is not null THEN
SET str = concat(str, ‘,’, fid);
SET rootId = fid;
ELSE
SET rootId = fid;
END IF;
END WHILE;
return str;
END
》》执行计划:

请问这类sql应如何优化
墨值悬赏

评论
