2016-11-18 4 views
0

저장된 SQL 프로 시저를 사용하여 DB에 여러 요청을 실행하는 무거운 Java 메서드를 대체하려고했습니다. 그것의 일을하고 있지만 훨씬 더 높은 성능 향상을 기대했습니다. 다음은 절차의 논리 (뿐만 아니라 자바 메소드) : 표 (목적)에서 ID의커서 및 임시 테이블을 사용할 때 MySQL 저장 프로 시저 성능 문제가 발생했습니다.

  1. 가져 오기 목록
  2. 반복 처리 목록 및 각 ID에 대한 표 2 (기록)에서 필드의 평균 값을 얻을
  3. 반환 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, ...

  • 단순히 결과를 제공 할 수있는 경우 TEMP 테이블을 사용하지 마십시오. 귀하의 경우 두 번 청크를 동시에 전달하려면 UNION ALL이 필요할 수 있습니다.