简体   繁体   中英

MySQL stored procedure performance issue when using cursor and temporary table

I tried to replace heavy Java method which runs multiple requests to the DB with stored SQL procedure. It's doing its work but I expected much higher performance improvement. The logic of the procedure(as well as Java method):

  1. Get list of IDs from table1(purpose)
  2. Iterate the list and get average value of a field from table2(record) for each id
  3. Return list of pairs id/average_value

Are there any efficiency issues in the procedure?

DROP PROCEDURE IF EXISTS test1.getGeneralAverage;
CREATE DEFINER=root@localhost 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

Several patterns to change...

  • Try to avoid CURSORs ; usually the entire operation can be done with a single SQL statement. That will be much faster.

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

  • Don't use a TEMP table when you can simply deliver the results. In your case, you may need a UNION ALL to deliver the two chunks at once.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM