4

I have a query which runs very fast as itself, but when I use that query as a function's body it suffers a great slowdown. Here is my test case:

/******************* 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

And here are query statements;

  • first, the query runs as itself
  • then the function is used with the same parameter:
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');

In this test, @id1 is set roughly in 0.03 seconds while @id2 arrives in 3.5 seconds (2 seconds at best). I wonder what causes this remarkable performance hit.

I need to use this function in another stored procedure, thus waiting 2-3 seconds for each row in the stored procedure kills my total performance.

Can anybody help me improve from this point?

4

1 回答 1

1

如果没有一组好的测试数据,很难玩这么多。对于您可以尝试更改的内容,我只有一些建议(咳嗽猜测咳嗽)。

显式声明函数参数的字符类型

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 聊天室联系我。

于 2011-11-18T16:09:29.860 回答