3

我正在使用最新版本的 MySQL(工作台)、Perl 和 DBI。

我有两个唯一的数据库,每个数据库都在唯一的服务器上。我在 Server1 上的 DB1 上查询 table1,加载到一个数组中,然后while将所述表插入到 Server2 上的 DB2 上的 table2 中。

它不是直接副本,因为我实际上是在表 1 上进行选择。

我正在尝试加快我的脚本或在必要时更改查询。

我正在使用绑定并将准备语句移出循环,这确实有帮助。但是,我最终还是调用了 160 万次插入到 table2/db2/server2 的调用,这会占用大量时间(每次调用 3100 秒或大约 2-3 毫秒)。

有两个子 &insert2tempData 在while循环中用于加载我的 DB2 table2。它被调用了 160 万次 AND query_dev_load_local_dbs 用于查询 DB1 然后调用第二个 sub。

为简单起见,我将此准备留在循环中,但在我的代码中,它不在循环中,而是在while调用此子的子中。

sub insert2tempData {
    $query4tmpData = $Locdbh_NetCool->prepare ("INSERT INTO kpincpolldata.kpitempData
        (monitoredObjectId, monitoredInstId, pollTime, tdwTime, errorCode, value)
        VALUES(?, ?, ?, ?, ?, ?)");

    $query4tmpData->execute($row[0], $row[1], $row[2], $row[3], $row[4],
                            $row[5]);
    warn "Problem in retrieving results", $query4tmpData->errstr(), "\n"
        if $query4tmpData->err();

} #End sun insert to tempData

这是用于查询 server1、DB1 和 table1 的主要 sub。它调用while循环

sub query_dev_load_local_dbs {
    $queryRemote = $Devdbh_NetCool->prepare("SELECT * FROM ncpolldata.pollData
                                   WHERE pollTime >= $STARTU AND pollTime < $ENDU
                                   AND monitoredObjectId = 1");

    $queryRemote->execute();

    while (@row = $queryRemote->fetchrow_array()) {

        #** Call to sub insert2tempData**
        &insert2tempData($Locdbh_NetCool);

        warn &print2log ("Problem in retrieving results"), $queryRemote->errstr(), "\n"
            if $queryRemote->err();
    } # End while

} # End sub query_dev_load_local_dbs
4

2 回答 2

4

我会使用fetchrow_arrayref(),而不是fetchrow_array()因为这样它就不必在每次获取一行时复制所有返回值。这应该会加快速度。你也可以看看bind_columns

然后我不太明白你对while循环和 的意思prepare,所以我还是这么说:将$query4tmpData=$Locdbh_NetCool->prepare移出 sub 并移到可以 d 一次的其他地方prepare,然后在 sub 中重用它。你可能有那个。


还有几件事:

  • 你应该总是use strictuse warnings. 我在你的潜艇上看不到my。请使用那些编译指示。他们让你的生活更轻松。
  • 当您无法INSERT读取“检索结果时出现问题”时发出的警告。如果发生这种情况,您可能会感到困惑。
于 2012-07-06T20:15:37.673 回答
4

您上面发布的代码完全有可能与您感知的性能问题无关。在您使用的数据库服务器上插入这么多行可能需要很长时间。这是我要看的:

  1. 关闭AutoCommit,它已启用。

    每次提交都会insert对性能产生严重影响,Server2具体取决于它的配置方式。完全有可能将整个过程集中到一个事务中可以加快速度。但这实际上取决于服务器的配置方式、索引的构建方式等。

    这使我们:

  2. 一个称职的 DBA 可能会提供帮助。

    请与管理您的 MySQL 服务器的人联系,看看他们是否可以帮助您进行故障排除。谁知道呢,他们甚至可能有 DBA 工具来帮助解决您的问题,而无需您在代码中做任何不同的事情,甚至允许您完全放弃此脚本。

    除非您是 DBA:

  3. 您可能会在Stack Exchange 网站上浏览 DBA。

您发布的代码中可能有一些小问题需要修复,但如果数据库是瓶颈,那就没关系了。找到瓶颈!

于 2012-07-06T23:21:19.343 回答