为什么我的Mysql看起来永远不会停止

时间:2015-07-06 19:20:38

标签: mysql select

我的sql循环永远不会结束为什么? 我在循环时做了一个简单的游标,但是我得到了一个无限循环,我找不到bug。 我没有性能问题它是一个无限循环,我有35K记录,但循环持续很长时间后,我停止执行,我无法得到它是怎么回事,循环应该是光标选择检索的确切计数

DROP PROCEDURE IF EXISTS tlaTempAmoutUSDTrades;
CREATE PROCEDURE tlaTempAmoutUSDTrades()
BEGIN
  DECLARE bDone INT;
  DECLARE pTradeGUID binary(16);    -- or approriate type
  DECLARE pTradeAmountUSD double;    -- or approriate type
  DECLARE curs CURSOR FOR  SELECT t.guid FROM trades as t
    JOIN `orderslogadd` as `o` on`t`.`orderId` = `o`.`orderId`
    JOIN `currencypairs` as `ccp` on`o`.`ccpair` = `ccp`.`id`
    JOIN `currencies` as `ccy1` on`ccp`.`currency1` = `ccy1`.`id`
    JOIN `currencies` as `ccy2` on`ccp`.`currency2` = `ccy2`.`id`
    left  JOIN tlaAmountUSD tau on tau.guid = t.guid
    WHERE tau.amountUSD is  null ;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;

    OPEN curs;

 setAmountUSD: LOOP
 FETCH curs INTO pTradeGUID;
        IF (bDone = 1) OR (pTradeGUID is null) THEN 
            LEAVE setAmountUSD;
        END IF;
        SET pTradeAmountUSD = (select  `crosUSDValV22`(`ccy1`.`id`,`ccy2`.`id`,`t`.`amount`,`t`.`amountCcy`,`t`.`dealtRate`,`t`.`guid`) as tradeAmountUSD
        FROM `trades` as t
        JOIN `orderslogadd` as `o` on`t`.`orderId` = `o`.`orderId`
        JOIN `currencypairs` as `ccp` on`o`.`ccpair` = `ccp`.`id`
        JOIN `currencies` as `ccy1` on`ccp`.`currency1` = `ccy1`.`id`
        JOIN `currencies` as `ccy2` on`ccp`.`currency2` = `ccy2`.`id`
        where t.guid=pTradeGUID);
        insert into tlaAmountUSD (guid,amountUSD) values (pTradeGUID,pTradeAmountUSD);

END LOOP setAmountUSD;

关闭诅咒;

END;

1 个答案:

答案 0 :(得分:0)

根据您在此处显示的内容,在从curs获取最后一行之后,将调用continue处理程序,bDone将设置为1,然后条件测试将是是的,循环将退出。这看起来不像是一个无限循环。

如果这是实际执行的代码,那么只需要时间来完成该过程。 (也许游标定义中的查询真的慢,或者循环体中的查询真的很慢......引用的表被锁定,或INSERT阻塞等等。

为了进行调试,您可以考虑在游标查询中添加LIMIT 1,看看是否可以让它完成一行,并查看需要多长时间。

您可以尝试注释掉正在执行此工作的过程的主体,然后执行获取,以查看需要多长时间。

此外,对两个查询(在游标中和循环中)运行EXPLAIN,验证是否正在使用适当的索引,以及查询计划是否合理。还要测试这些查询,以验证它们是否返回了您期望的结果。

这将有助于缩小问题所在。

除非您指定了不同的分隔符,否则显示的CREATE PROCEDURE语句将抛出错误;否则,遇到的第一个分号将(过早地)“结束”存储过程定义

 CREATE PROCEDURE tlaTempAmoutUSDTrades()
 BEGIN
   DECLARE bDone INT;
                    ^

要创建该过程,您需要执行以下操作:

 DELIMITER $$

 CREATE PROCEDURE tlaTempAmoutUSDTrades()
 BEGIN
   DECLARE bDone INT;
   -- ...
 END $$

 DELIMITER ;