mysql 在查询语句中使用自定义函数速度非常慢

AlonsoLiu 2021-04-30 03:52:17
我发现mysql在查询语句中使用自定函数速度会非常慢,哪怕做很简单的计算,只要用到了自定义函数,相比使用原生的函数要慢一个数量级。而且在自定义函数中每多执行一条哪怕是最简单的语句都会变得更慢。
下面是我做的一个简单的测试:
首先创建一张包括一万条数据的表:
create table tmp (s varchar(1000)) as select .... limit 10000;
然后创建3个自定义函数,简单的计算字符长度并且做10次加法:

mylength1:在一条语句中加十次;

DELIMITER $$
CREATE FUNCTION `mylength1`( s1 VARCHAR(255)) RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE s1_len, i INT;
SET s1_len = 0;
SET s1_len = s1_len+length(s1)+length(s1)+length(s1)+length(s1)+length(s1)+length(s1)+length(s1)+length(s1)+length(s1)+length(s1);
RETURN s1_len;
END;$$

mylength2:通过十条语句中完成加十次;

DELIMITER $$
CREATE FUNCTION `mylength2`( s1 VARCHAR(255)) RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE s1_len, i INT;
SET s1_len = 0;
SET s1_len = s1_len+length(s1);
SET s1_len = s1_len+length(s1);
SET s1_len = s1_len+length(s1);
SET s1_len = s1_len+length(s1);
SET s1_len = s1_len+length(s1);
SET s1_len = s1_len+length(s1);
SET s1_len = s1_len+length(s1);
SET s1_len = s1_len+length(s1);
SET s1_len = s1_len+length(s1);
SET s1_len = s1_len+length(s1);
RETURN s1_len;
END;$$


mylength3:使用while循环语句完成加十次;

DELIMITER $$
CREATE FUNCTION `mylength3`( s1 VARCHAR(255)) RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE s1_len, i INT;
SET s1_len = length(s1);
SET i = 0;
WHILE i <= 10 DO
SET s1_len = s1_len+length(s1);
SET i = i + 1;
END WHILE;
RETURN s1_len;
END;$$


再对比直接使用原生的函数,用于对比的 sql 如下:

select max(length(s)) a from tmp;
select max(length(s)+length(s)+length(s)+length(s)+length(s)+length(s)+length(s)+length(s)+length(s)+length(s)) a from tmp;
select max(mylength1(s)) from tmp a;
select max(mylength2(s)) from tmp a;
select max(mylength3(s)) from tmp a;
select max(levenshtein('任何一个字符串', s)) from tmp a;


执行结果如下:


从上面的结果可以看到:
1. 调用原生函数一次和10次的用时差不多,都是0.01秒就完成了;实际上调用10次要稍慢,有时候会是0.02秒,但差别不大;
2. 调用mylength1,自定义函数在一个语句中完成10次加法,耗时达到0.39秒,增加了几十倍;
3. 调用mylenght2,自定义函数使用10条语句完成10次加法,耗时达到0.52秒,再增加了30%;
4. 调用mylength3,自定义函数使用while循环10次做加法,耗时达到了1.06秒,再次翻倍;
5. 调用levenshtein自定义函数,耗时达到了9.21秒,再次增加了近10倍;

可以说mysql查询中调用自定义函数的效率惊人的低。是有什么解决办法吗?
我在论坛上找到这篇文章,但是并不能解决这个问题:
https://bugs.mysql.com/bug.php?id=34254
...全文
2189 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

升级版本就好了

AlonsoLiu 2021-05-24
  • 打赏
  • 举报
回复
看来mysql的函数就是这么慢了,还是出乎我的意料,作为使用这么普遍的数据库,这么基本的功能居然会有这么严重的性能问题。 用C编写的UDF执行速度快(正常)吗,你是用过的?
引用 2 楼 老紫竹 的回复:
用SQL写UDF,本身就慢,不适合大数据量处理,建议 1、用内置函数【直接组合】 2、改用C编写的UDF
AlonsoLiu 2021-05-24
  • 打赏
  • 举报
回复 1
我说的自定义函数是用 CREATE FUNCTION 创建的函数,需要在SQL中(例如在SELECT语句里)调用。你说转换为存储过程是指什么呢?
引用 1 楼 顾染尘 的回复:
把自定义函数转换为存储过程试试?
yuanaux 2022-08-19
  • 举报
回复
@AlonsoLiu 楼主解决了吗? 同样发现了这个问题,单独执行自定义函数比较快100多毫秒,把函数加载查询条件就需要3秒!数据类型是一致的,而且表数据才20条; 之前使用Oracle这种是日常操作
老紫竹 2021-05-12
  • 打赏
  • 举报
回复
用SQL写UDF,本身就慢,不适合大数据量处理,建议 1、用内置函数【直接组合】 2、改用C编写的UDF
顾染尘 2021-05-12
  • 打赏
  • 举报
回复
把自定义函数转换为存储过程试试?

56,681

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧