【问题标题】:mysql cursor taking long to executemysql游标需要很长时间才能执行
【发布时间】:2013-08-21 12:59:21
【问题描述】:

我编写了一个使用游标循环遍历行的过程。执行时间过长。

    CREATE PROCEDURE test_port()
    BEGIN
    declare done BOOL default FALSE;
    declare I,J,C,P,NOB int default 0;
    declare n,k,t int default 0;
    declare Lid int default 0;
    declare inTS timestamp;
    select max(id) into n from MAIN_TBL;
    select ctrValue into k from ID_CNT;
    set k=k+1;
    WHILE k<=n
    do
            select SourcePort,DestPort,LinkID,NoOfBytes,insertTime into I,J,Lid,NOB,inTS from MAIN_TBL where id=k;
            select count(*) into t from APP_PORTMAP_MSTR where Port in (I,J);
            IF(t=1) THEN
                    select Port into P from APP_PORTMAP_MSTR where Port in (I,J);
                    SET C=0;
                    select count(*) INTO C from LINK_APP_TBL where LinkID=Lid and Port=P;
                    insert into TRAFFIC_HIST_TBL(LinkID,Port,NoOfBytes,Time_1) values(Lid,P,NOB,inTS);
                    IF(C=0) THEN
                            insert into LINK_APP_TBL(Port,LinkID) values(P,Lid);
                    END IF;
            ELSE
                    if(I>J && J<>0) THEN
                            SET C=0;
                            select count(*) INTO C from LINK_APP_TBL where LinkID=Lid and Port=J;
                            IF(C=0) THEN
                                    insert into LINK_APP_TBL(Port,LinkID) values(J,Lid);
                                    insert into TRAFFIC_HIST_TBL(LinkID,Port,NoOfBytes,Time_1) values(Lid,J,NOB,inTS);
                            END IF;
                    ELSE
                            SET C=0;
                            select count(*) INTO C from LINK_APP_TBL where LinkID=Lid and Port=I;
      IF(C=0) THEN
                                    insert into LINK_APP_TBL(Port,LinkID) values(I,Lid);
                                    insert into TRAFFIC_HIST_TBL(LinkID,Port,NoOfBytes,Time_1) values(Lid,I,NOB,inTS);
                            END IF;
                    END IF;
            END IF;
    SET k=k+1;
    END WHILE;
    END$$
    \d ;



速度慢的可能原因是“插入”语句,但我们可以通过任何方式提高性能吗?它一次处理大约 10K 条记录。

【问题讨论】:

  • 它基本上检查主表中是否存在端口,如果存在,则使用标准端口进行条目。否则,较小的端口被视为标准端口并进行条目。

标签: mysql sql stored-procedures cursor


【解决方案1】:

每秒 10k 是一个很大的数字...您可以尝试删除一些您不使用的索引,或者您可以将数据文件移动到更快的磁盘(如 SSD),这会产生巨大的差异...

【讨论】:

  • 我认为你是对的,但到目前为止我还没有任何这样的规定,因为我们正处于 POC 阶段。我可以通过的唯一方法是尽可能尝试提高效率。另外,我在表格上没有太多索引... :(
  • 那么你是否用解释检查了你的每一个选择?没有索引的查询也会导致问题,也许你的问题是你的选择?另外,myisam 表会在写入时锁定表,innodb 只锁定行,你的表类型是什么?
  • 我的表是 innodb 类型的
  • 我不知道这对你来说是否可行,但也许你可以将内存表用于 POC 阶段。我认为生产阶段的 SSD 磁盘似乎是您的最佳解决方案,每秒 10k 对普通磁盘来说确实很高。
【解决方案2】:

嗯,仔细分析了processlist,发现“查询结束”状态需要很长时间。

因此,在搜索了一些线程后,我发现将 innodb_flush_log_at_trx_commit 设置为 0 或 2 将加快操作速度,但它们禁止 innodb 成为 ACID 投诉。

在操作系统崩溃或电源故障的情况下,更改值可能会导致 1 条指令丢失。

参考: UPDATE statements are in "query end state"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 2011-03-14
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多