0

这是从 SQL 获取数据的简单 perl 脚本。读取数据并写入文件 OUTFILE,每 10000 行在屏幕上打印数据。

我很好奇的一件事是,在屏幕上打印数据非常快(在 30 秒内)终止,但是,在文件上获取和写入数据的速度非常慢(30 分钟后)。

数据量不大。输出文件大小小于 100Mbyte。

while ( my ($a,$b) = $curSqlEid->fetchrow_array() ) 
{
    printf OUTFILE ("%s,%d\n", $a,$b);
    $counter ++;
    if($counter % 10000 == 0){
        printf ("%s,%d\n", $a,$b);
    }
}  
$curSqlEid->finish();
$dbh->disconnect();
close(OUTFILE);
4

3 回答 3

3

你正在遭受缓冲。

STDERR 以外的句柄默认情况下会被缓冲,并且大多数句柄都使用块缓冲。这意味着 Perl 将等到有 8KB* 的数据要写入,然后再向系统发送任何内容。

STDOUT 是特殊的。当连接到终端时(并且仅在那时),它使用不同类型的缓冲:行缓冲。使用行缓冲时,每次在要写入的数据中遇到换行符时都会刷新数据。

您可以通过运行看到这一点

$ perl -e'print "abc"; print "def"; sleep 5; print "\n"; sleep 5;'
[ 5 seconds pass ]
abcdef
[ 5 seconds pass ]

$ perl -e'print "abc"; print "def"; sleep 5; print "\n"; sleep 5;' | cat
[ 10 seconds pass ]
abcdef

解决方案是关闭缓冲。

use IO::Handle qw( );  # Not needed on Perl 5.14 or later
OUTFILE->autoflush(1);

* — 8KB 是默认值。它可以在编译 Perl 时进行配置。在 5.14 之前,它曾经是不可配置的 4KB。

于 2012-04-26T20:57:03.400 回答
0

I think you are seeing the output file size as 0 while the script is running and displaying on the console. Do not go by that. The file size will show up only once the script has finished. This is due to output buffering.

Anyways, the delay cannot be as large as 30 min. Once the script is done, you should see the output file data.

于 2012-04-27T04:25:52.920 回答
0

我尝试了各种方法,但最终的结论是 python 和 perl 与 DB 的处理数据流基本不同。看起来在 perl 中,可以在从 DB 传输数据的同时逐行处理数据。但是,在 Python 中,它需要等到从服务器下载整个数据才能处理它。

于 2013-01-08T05:58:00.150 回答