2016-11-18 217 views
0

我尝试用存储的SQL过程替换运行多个请求的重度Java方法。 它正在完成它的工作,但我期望性能得到更高的改进。 程序的逻辑(以及Java方法):从表1(目的)的ID使用游标和临时表时MySQL存储过程的性能问题

  1. 获取列表
  2. 迭代列表,并从表2(记录)字段的平均值为每个ID
  3. 返回列表对ID的 /AVERAGE_VALUE

是否有手术中的任何效率问题?

DROP PROCEDURE IF EXISTS test1.getGeneralAverage; 
CREATE [email protected] PROCEDURE getGeneralAverage() 
    BEGIN 
    DECLARE p_id BIGINT(20); 
    DECLARE exit_loop BOOLEAN; 
    DECLARE cur CURSOR FOR 
      SELECT purpose_id FROM purpose 
       WHERE purpose.type = 'GENERAL' 
       AND (SELECT COUNT(*) > 0 FROM record 
         WHERE record.purpose_id=purpose.purpose_id) is true; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE; 
    CREATE TEMPORARY TABLE IF NOT EXISTS general_average 
      (id BIGINT(20), average DOUBLE) ENGINE=memory; 
    TRUNCATE TABLE general_average; 
    OPEN cur; 
    average_loop: LOOP 
     FETCH cur INTO p_id; 
     INSERT INTO test1.general_average (id, average) 
      VALUES (p_id, (SELECT AVG(amount) FROM record 
          WHERE record.purpose_id=p_id)); 
     IF exit_loop THEN 
     CLOSE cur; 
     LEAVE average_loop; 
     END IF; 
    END LOOP average_loop; 
    INSERT INTO test1.general_average (id, average) 
     VALUES (0, 
      (select avg(amount) from record where purpose_type='CUSTOM')); 
    SELECT * FROM general_average; 
    END 

回答

1

几种模式改变...

  • 尽量避免CURSORs;通常整个操作可以使用单个SQL语句完成。这将会更快。

  • INSERT ... VALUES (0, (SELECT ...)) - >INSERT ... SELECT 0, ...

  • 不要使用临时表时,你可以简单地提供的结果。在你的情况下,你可能需要一个UNION ALL一次交付两个块。