gpt4 book ai didi

mysql - 在 Perl DBI 中处理大量结果的最有效方法是什么?

转载 作者:行者123 更新时间:2023-11-29 03:54:00 24 4
gpt4 key购买 nike

我有一个包含几百万行的表。目前,我正在通过这样做一次处理 10,000 个:

for (my $ival = 0; $ival < $c_count; $ival += 10000)
{
my %record;

my $qry = $dbh->prepare
( "select * from big_table where address not like '%-XX%' limit $ival, 10000");
$qry->execute();

$qry->bind_columns( \(@record{ @{$qry->{NAME_lc} } } ) );

while (my $record = $qry->fetch){
this_is_where_the_magic_happens($record)
}
}

我做了一些基准测试,我发现准备/执行部分虽然最初很快,但在多个 10,000 行批处理后速度会大大降低。这是一种愚蠢的写法吗?我只知道如果我试图一次性选择所有内容,这个查询将永远持续下去。

这是日志中的一些片段:

(Thu Aug 21 12:51:59 2014) Processing records 0 to 10000
SQL Select => 1 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU)
(Thu Aug 21 12:52:13 2014) Processing records 10000 to 20000
SQL Select => 1 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(Thu Aug 21 12:52:25 2014) Processing records 20000 to 30000
SQL Select => 2 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(Thu Aug 21 12:52:40 2014) Processing records 30000 to 40000
SQL Select => 5 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(Thu Aug 21 12:52:57 2014) Processing records 40000 to 50000
SQL Select => 13 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU)
...
(Thu Aug 21 14:33:19 2014) Processing records 650000 to 660000
SQL Select => 134 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU)
(Thu Aug 21 14:35:50 2014) Processing records 660000 to 670000
SQL Select => 138 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(Thu Aug 21 14:38:27 2014) Processing records 670000 to 680000
SQL Select => 137 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
(Thu Aug 21 14:41:00 2014) Processing records 680000 to 690000
SQL Select => 134 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)

采用其他方式会更快吗?我是否应该删除“where”子句并在循环中丢弃我不想要的结果?

感谢您的帮助。

最佳答案

其他人提出了有用的建议。我只会添加一些想到的想法......

  • 首先,请看我的旧版但仍然非常相关Advanced DBI Tutorial .特别是第 80 页,它解决了通过大型结果集进行分页的问题,这与您的情况类似。它还涵盖分析和 fetchrow_hashrefbind_columns

  • 考虑创建一个带有自动递增字段的临时表,通过 INSERT ... SELECT ... 语句将所需数据加载到其中,然后在其上构建/启用索引自动增量字段(这比加载已启用索引的数据更快),然后使用键值从该临时表中选择行范围。这对于获取来说将非常很快,但是构建临时表需要前期成本。

  • 考虑启用 mysql_use_resultDBD::mysql .驱动程序不会将所有行加载到驱动程序的内存中,而是在行从服务器流入时开始将行返回给应用程序。这减少了延迟和内存使用,但以持有表锁为代价。

  • 您可以结合使用 mysql_use_result 和我之前的建议,但结合使用 SELECT SQL_BUFFER_RESULT ... 可能更简单。两者都可以避免锁定问题(无论如何这对您来说可能不是问题)。每the docs , SQL_BUFFER_RESULT “强制将结果放入临时表”。 (琐事:我想我很久以前就向 Monty 建议了 SQL_BUFFER_RESULT。)

关于mysql - 在 Perl DBI 中处理大量结果的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25434015/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com