
MySQL手册中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应如何优化
复制