避免在存储过程中多次执行相同的计算

时间:2013-04-04 10:44:26

标签: mysql stored-procedures

我有一个存储过程,我重复计算,如

DROP PROCEDURE sp_alters;
DELIMITER $$


CREATE
    /*[DEFINER = { user | CURRENT_USER }]*/
    PROCEDURE `sp_alters`()
    /*LANGUAGE SQL
    | [NOT] DETERMINISTIC
    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }
    | COMMENT 'string'*/
    BEGIN
SELECT  
   `fn_getDiscount`(`t_orderitem`.`a_orderitemid`,`t_orderitem`.`a_quantity`)  AS `discount`,

    fn_getnewvalues(`fn_getDiscount`(`t_orderitem`.`a_orderitemid`,`t_orderitem`.`a_quantity`),a_orderitemid) as newvalue

FROM t_orderitem;
    END$$

DELIMITER ;

在这里你看到我在同一存储过程中调用fn_getDiscount 2次。所以我想避免它。我可以存储到变量中并使用它吗?

2 个答案:

答案 0 :(得分:0)

是的,你可以。

您必须准备句子,然后重复使用。

SET @your_variable = "this is some text you can repeat";
SET @your_query=CONCAT("
INSERT INTO something
", @some_variable,"
WHERE other_things");

PREPARE stmt FROM @your_query;
EXECUTE stmt;

这是您可以按照自己喜欢的方式工作和重用的基本结构。

答案 1 :(得分:0)

如果您显示完整的语句并且至少显示了该过程的标题,那将会有所帮助,但是看看您提供的作为代码看起来是代码的片段 - 并且fn_getDiscount似乎是一个功能而不是程序。

准备语句只会避免每次引用时都必须解析语句 - 它不会避免执行语句的开销。

虽然,IIRC,MySQL当前没有实现这一点,任何声明为DETERMINISTIC的函数(即将始终为给定的一组输入生成相同的输出而没有副作用)是可缓存的 - 这可能在将来发生变化,因此它将是添加它是一个好主意。

如果函数是确定的,那么你可以通过使用子查询避免多次调用它:

SELECT func_result
FROM (SELECT expensive_function(your_columns...) AS func_result
      FROM your_table
      WHERE your_column_a BETWEEN 1 AND 100) AS ilv
WHERE func_result > 50;

在函数的过程中,您可以调用其他函数并将结果存储在变量中 - 这是使用存储函数/过程的主要原因。