Mysql 存储函数性能问题

标签 mysql stored-functions

我有一个查询本身运行速度非常快,但是当我将该查询用作函数体时,它的运行速度会大大降低。 这是我的测试用例:

/******************* my function definition *********************/
DELIMITER $$

CREATE DEFINER=`root`@`%` FUNCTION `GetNextScheduleForProgram`(
  prog_id varchar(10)
) RETURNS varchar(10) CHARSET latin5
    DETERMINISTIC
BEGIN

  DECLARE scheduleid varchar(10);
  SET scheduleid =
  (
      SELECT sc.ScheduleID
        FROM Schedule sc
       WHERE sc.ProgramID=prog_id
         AND sc.StartDate BETWEEN now() and date_add(now(), interval 3 day)
    ORDER BY sc.StartDate ASC
       LIMIT 1

  );
  RETURN scheduleid;

END

这里是查询语句;

  • 首先,查询自己运行
  • 然后函数与相同的参数一起使用:
SET @id1 = (SELECT sc.ScheduleID
              FROM Schedule sc
             WHERE sc.ProgramID='23860'
               AND sc.StartDate BETWEEN now() and date_add(now(), interval 3 day)
          ORDER BY sc.StartDate ASC
             LIMIT 1);
SET @id2 = GetNextScheduleForProgram('23860');

在此测试中,@id1 大约在 0.03 秒内设置,而@id2 在 3.5 秒内到达(最多 2 秒)。我想知道是什么导致了这种显着的性能下降。

我需要在另一个存储过程中使用此函数,因此存储过程中每一行等待 2-3 秒会降低我的整体性能。

有人可以帮助我改进这一点吗?

最佳答案

如果不能访问一组良好的测试数据,就很难玩这么多。对于您可以尝试改变的事情,我只有一些建议(咳咳猜测咳咳)。

明确声明函数参数的字符类型

CREATE DEFINER=`root`@`%` FUNCTION `GetNextScheduleForProgram`(
  prog_id varchar(10) CHARSET latin5
...

只返回函数中的子查询

BEGIN
  RETURN
  (
    SELECT SQL_NO_CACHE sc.ScheduleID
    FROM Schedule AS sc
    WHERE sc.ProgramID = prog_id
      AND sc.StartDate BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 3 DAY)
    ORDER BY sc.StartDate ASC
    LIMIT 1
  );
END

为了准确测试,使用SQL_NO_CACHE

我能够用上面的代码创建函数,它在 MySQL 5.1.45 下运行良好。为了准确测试,您的查询需要这一行,否则您不能真正相信您返回的数字以了解您的查询有多昂贵。

向 RDBMS 神灵献祭一只鸡

这就是我现在的全部 - 我对这个问题很好奇,所以如果你愿意在某处粘贴一些测试数据以便我可以进行更多实验,我愿意这样做。

随时在 MySQL chat room 中 ping 我如果您想就这个听起来很时髦的问题大谈特谈。

关于Mysql 存储函数性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8170066/

相关文章:

java - 多对多删除集 NULL

mysql - 在 IN() 运算符中使用 Mysql 存储函数的返回值

MySQL 使用 if then else 方法将一条记录选择到函数内部的变量中

带有嵌套 IF...END IF 的 MySQL 存储函数,语法错误,在 '' 附近使用正确的语法

function - 类似宏的函数作为 postgresql 中的过滤器

mysql - 使用 SQL 比较日期间隔

mysql - 如何连接 2 个表并匹配空值

php - 无法将数据写入数据库

mysql UNION 错误结果?

mysql - 修改函数以调用/单步执行表