以下是从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);
答案 0 :(得分: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。它可以是configured when Perl is compiled。它曾经是一个不可配置的4KB,直到5.14。
答案 1 :(得分:0)
我认为您在脚本运行并在控制台上显示时看到输出文件大小为0。不要那样做。只有脚本完成后才会显示文件大小。这是由于输出缓冲。
无论如何,延迟不能大到30分钟。脚本完成后,您应该看到输出文件数据。
答案 2 :(得分:0)
我尝试了各种各样的东西,但最后的结论是python和perl与DB的处理数据流基本不同。它看起来像在perl中,可以在数据从DB传输时逐行处理数据。但是,在Python中,它需要等到从服务器下载整个数据才能处理它。