2010-05-19 5 views
3

J'ai écrit une procédure stockée en utilisant le curseur dans mysql mais cette procédure prend 10 secondes pour aller chercher le résultat alors que ce jeu de résultats n'a que 450 enregistrements donc, je veux savoir pourquoi cette procédure prend cela beaucoup de temps pour aller chercher le disque.Procédure stockée utilisant le curseur dans mySql

procédure

comme ci-dessous:

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 ; 

Répondre

0

C'est la nature des curseurs pour être lent, il n'y a rien dans votre code qui est évidemment mal conçu. Rappelez-vous que pour chacune de vos 450 lignes, votre curosr itère sur vous émettant une ou deux déclarations. Chacune de ces requêtes sera exécutée par elle-même. L'émission de 450 à 900 relevés comme celui-ci prendrait probablement le même temps.

C'est pourquoi vous devriez, autant que possible, essayer d'éviter les curseurs.

Il semble que vous souhaitiez, en fonction d'un certain critère, sélectionner une valeur ou une autre. Peut-être que vous divisez votre requête en deux requêtes select (pour chaque cas de critère) et UNION le résultat.

+0

ok comment puis-je accélérer cette procédure sans utiliser de curseur. Supposons que si j'ai 10.000 enregistrements alors la même procédure prend plus de 2 minutes. – RAVI

+0

quelle est la solution alternative pour la même procédure. J'ai essayé la même procédure pour 10.000 enregistrements puis cela prend plus de 2 minutes pour aller chercher le résultat ... – RAVI

+0

@RAVI: Eh bien, je ne vais pas faire * votre * travail ici. –

1

s'il vous plaît exécuter ce qui suit et coller tous les résultats dans http://pastie.org/ vous devriez remplacer le ?? dans les instructions de sélection avec des valeurs de test appropriées avant l'exécution

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

Merci, mais j'ai résolu le problème sans utiliser le curseur et obtenir le bon résultat dans une requête SQL simple ligne en utilisant la jointure gauche. – RAVI

+1

bon de savoir que vous êtes venu à vos sens –

Questions connexes