2016-11-18 4 views
0

ストアドSQLプロシージャを使用してDBに複数のリクエストを実行する重いJavaメソッドを置き換えようとしました。 それは仕事をしていますが、私ははるかに高いパフォーマンスの向上を期待していました。 手順(ならびにJavaメソッド)の論理:カーソルとテンポラリテーブルを使用するとMySQLストアドプロシージャのパフォーマンスに問題が発生する

  1. TABLE1から(目的)のIDのリストを取得
  2. 反復リストと各IDの表2(レコード)からのフィールドの平均値を取得します
  3. 戻りリスト
  4. ペアの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を避けるようにしてください。通常、1つのSQL文で操作全体を実行できます。それははるかに速くなります。

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

  • あなたは、単に結果を出すことができたときにTEMPテーブルを使用しないでください。あなたの場合、2つのチャンクを一度に配信するには、UNION ALLが必要な場合があります。

関連する問題