Хранимая процедура с использованием курсора в mySql - PullRequest
3 голосов
/ 19 мая 2010

Я написал хранимую процедуру с использованием курсора в mysql, но эта процедура занимает 10 секунд, чтобы получить результат, в то время как этот набор результатов имеет только 450 записей, поэтому я хочу знать, почему для этой процедуры требуется столько времени для получения записи .

процедура, как показано ниже:

DELIMITER //
DROP PROCEDURE IF EXISTS curdemo123//

CREATE PROCEDURE curdemo123(IN Branchcode int,IN vYear int,IN vMonth int)
   BEGIN
      DECLARE  EndOfData,tempamount INT DEFAULT 0;
      DECLARE tempagent_code,tempplantype,tempsaledate CHAR(12);
      DECLARE tempspot_rate DOUBLE;
      DECLARE var1,totalrow INT DEFAULT 1;
      DECLARE cur1 CURSOR FOR 
              select SQL_CALC_FOUND_ROWS ad.agentCode
                   , ad.planType
                   , ad.amount
                   , ad.date 
                from adplan_detailstbl ad 
               where ad.branchCode=Branchcode 
                 and (    ad.date between '2009-12-1' 
                                      and '2009-12-31')
               order by ad.NUM_ID asc;
      DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET EndOfData = 1;
      DROP TEMPORARY TABLE IF EXISTS temptable;

      CREATE TEMPORARY TABLE temptable (
             agent_code varchar(15)
           , plan_type char(12)
           , sale double
           , spot_rate double default '0.0', dATE DATE
      );

      OPEN cur1;
      SET totalrow=FOUND_ROWS();
      while var1 <= totalrow DO
         fetch cur1 into tempagent_code
                        ,tempplantype
                        ,tempamount
                        ,tempsaledate;

         IF( (    tempplantype='Unit Plan' 
               OR tempplantype='MIP'
             ) OR tempplantype='STUP') THEN

            select spotRate into tempspot_rate 
              from spot_amount 
              where ((    monthCode=vMonth 
                      and year=vYear) 
                    and (     (     agentCode=tempagent_code 
                                and branchCode=Branchcode) 
                          and (planType=tempplantype)
              ));

            INSERT INTO temptable VALUES(
                tempagent_code
               ,tempplantype
               ,tempamount
               ,tempspot_rate
               ,tempsaledate)
           ;
      else
         INSERT INTO temptable(
              agent_code
             ,plan_type
             ,sale,dATE) 
         VALUES( tempagent_code,tempplantype,tempamount,tempsaledate);
      END IF;

      SET var1=var1+1;
END WHILE;
CLOSE cur1;
select * from temptable;
DROP TABLE  temptable;
END //
DELIMITER ;

Ответы [ 2 ]

1 голос
/ 19 мая 2010

, пожалуйста, запустите следующее и вставьте ВСЕ результаты в http://pastie.org/ Вы должны заменить ?? в операторах выбора с правильными значениями теста перед выполнением

 show table status like 'adplan_detailstbl'\G
 show create table adplan_detailstbl \G
 show indexes from adplan_detailstbl;

 explain select 
  ad.* 
 from 
  adplan_detailstbl ad 
 where 
  ad.branchCode = ?? and ad.date between '2009-12-01' and '2009-12-31'
 order by 
  ad.NUM_ID;

 show table status like 'spot_amount'\G
 show create table spot_amount \G
 show indexes from spot_amount;

 explain select * from 
  spot_amount
 where 
  monthCode=?? and year=?? and agentCode=?? and branchCode=?? and planType=??;
0 голосов
/ 19 мая 2010

Природа курсоров медленная, в вашем коде нет ничего, что было бы плохо спроектировано. Помните, что для каждого из ваших 450 рядов, которые ваш curosr повторяет, вы выдает один или два оператора. Каждый из этих запросов будет выполняться самостоятельно. Выпуск 450-900 таких заявлений сам по себе, вероятно, займет аналогичное время.

Вот почему вы должны, по возможности, избегать курсоров.

Похоже, вы хотите, в зависимости от определенных критериев, выбрать один набор значений ov или другой. Возможно, вы разбили свой запрос на два запроса на выборку (для каждого случая критериев) и объединили результат.

...