Perl SQL 文件写入延迟



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

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

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

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

你正在遭受缓冲。

默认情况下,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 时进行配置。它曾经是不可配置的 4KB,直到 5.14。

我认为当脚本正在运行并在控制台上显示时,您会看到输出文件大小为 0。不要这样。文件大小仅在脚本完成后显示。这是由于输出缓冲。

无论如何,延迟不能大到30分钟。脚本完成后,您应该会看到输出文件数据。

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

最新更新