Mysql 如何提高Perl/DBI脚本的性能,该脚本从一个数据库服务器中选择100多万行并将它们插入另一个数据库服务器?
我使用的是MySQL工作台、Perl和DBI的最新版本 我有两个唯一的数据库,每个数据库都位于唯一的服务器上。我在Server1上的DB1上查询table1,将其加载到一个数组中,然后在将所述表插入Server2上DB2上的table2时使用 它不是直接复制,因为我实际上是在表1上进行选择 我正在尝试加快脚本速度,或者在必要时更改查询 我使用了绑定,并将prepare语句移出了循环,这确实很有帮助。然而,我最终还是调用了160万次来插入table2/db2/server2,这将占用大量的时间3100秒,即每次调用大约2-3ms 有两个子类&insert2tempData,在while循环中用于加载我的DB2表2。它被调用160万次,查询用于查询DB1的\u dev\u load\u local\u dbs,然后调用第二个子系统 为了简单起见,我将这个prepare放在循环中,但在我的代码中,它不在while循环中,而是在调用这个sub的sub中Mysql 如何提高Perl/DBI脚本的性能,该脚本从一个数据库服务器中选择100多万行并将它们插入另一个数据库服务器?,mysql,perl,dbi,Mysql,Perl,Dbi,我使用的是MySQL工作台、Perl和DBI的最新版本 我有两个唯一的数据库,每个数据库都位于唯一的服务器上。我在Server1上的DB1上查询table1,将其加载到一个数组中,然后在将所述表插入Server2上DB2上的table2时使用 它不是直接复制,因为我实际上是在表1上进行选择 我正在尝试加快脚本速度,或者在必要时更改查询 我使用了绑定,并将prepare语句移出了循环,这确实很有帮助。然而,我最终还是调用了160万次来插入table2/db2/server2,这将占用大量的时间31
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的主要子项。它调用while循环
我会使用fetchrow\u数组,而不是fetchrow\u数组,因为这样它就不必在每次获取行时复制所有返回值。这应该会使事情加快一点。你也可以看看
然后我没有完全理解你对while循环和prepare的意思,所以我还是这么说:将$query4tmpData=$Locdbh_NetCool->prepare移出sub,并移到其他可以准备一次的地方,然后在sub中重用它。你可能已经做到了
还有几件事:
您应该始终使用警告。我看不到你的潜艇。请用那些pragmas。他们让你的生活更轻松。
无法插入时发出的警告读取检索结果时出现的问题。如果发生这种情况,你可能会感到困惑。
您在上面发布的代码完全可能与您感知到的性能问题无关。在正在使用的数据库服务器上插入这么多行可能需要很长时间。下面是我要看的: 关闭自动提交,它已启用 根据Server2的配置方式,每次插入时提交都会对其性能产生严重影响。将整个过程分批处理到一个事务中完全有可能加快速度。但这实际上取决于服务器的配置方式、索引的构建方式等 这让我们想到: 有能力的DBA可能会提供帮助 与管理MySQL服务器的人联系,看看他们是否能帮助您解决问题。谁知道呢,他们甚至可能有DBA工具来帮助解决您的问题,而无需您在代码中做任何不同的操作,甚至允许您完全废弃此脚本 除非您是DBA: 您可以为DBA四处寻找
在您发布的代码中可能有一些小问题需要修复,但是如果数据库是瓶颈,那就无关紧要了。找到瓶颈 不太清楚你在问什么。这是工作代码吗?您的问题是关于提高性能吗?需要插入很多行。根据表2的设计方式,它可能与上述代码没有任何关系。您是在一次插入中执行一次提交,还是在一个事务中执行所有插入?关于表格设计,您是否咨询过DBA类型?Giles,是的,它工作得很好,是的,我想提高性能。使用批量导入/导出。选择输入输出文件并加载数据填充??好建议。希望OP会考虑到这一点,即使它不会直接加快处理速度。@John-谢谢。是的,我确实使用了strict and warning,我只是没有将该代码包括在内。是的,在我的生产代码中,我确实有任何循环中的prepare语句。@John Simb-Giles我将测试数组引用,我打赌这将节省我很多时间。我还将学习Bind Col。我刚刚回顾了我的MySql参考资料,这两件事作为选项列出。谢谢大家的精彩回复。我会向你汇报我的情况success@John无论是谁为了澄清我的问题而编辑了我的问题,谢谢。我确实知道服务器2不是生产服务器材料。我运行了一些测试,除了脚本的要求之外,服务器2的ram非常少,cpu也比较旧。我怀疑这与未完全优化的代码相结合是我的问题。我计划用更小的数据集完成优化和测试。然后我会把它转移到生产上。
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