在mySql中使用游标的存储过程

时间:2010-05-19 06:32:22

标签: mysql stored-procedures cursor

我在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 个答案:

答案 0 :(得分:1)

请运行以下内容并将所有结果粘贴到http://pastie.org/ 你应该更换??在执行

之前在具有适当测试值的select语句中
 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=??;

答案 1 :(得分:0)

游标的本质是缓慢的,你的代码中没有任何东西显然是糟糕的设计。请记住,对于您的450行中的每一行,您的curosr迭代您发出一个或两个语句。每个查询都将自行运行。单独发布450-900这样的声明可能会花费相同的时间。

这就是为什么你应该尽可能地避免使用游标。

看起来你想要,根据一定的标准,选择一个设置ov值或另一个。也许你将查询分成两个选择查询(对于每个条件的情况)和UNION结果。