如何逐行从大 table 中获取数据
How to get data from big table row by row
我需要从 mysql table 获取所有数据。到目前为止我尝试过的是:
my $query = $connection->prepare("select * from table");
$query->execute();
while (my @row=$query->fetchrow_array)
{
print format_row(@row);
}
但总有一个但是...
Table 有大约 600M 行,显然所有查询结果都在 execute()
命令后存储在内存中。内存不足:(
我的问题是:
有没有办法使用 perl DBI 从 table 逐行获取数据?像这样:
my $query = $connection->prepare("select * from table");
while (my @row=$query->fetchrow_array)
{
#....do stuff
}
顺便说一句,分页速度很慢:/
fetchall_arrayref
方法有两个参数,第二个参数允许您限制一次从 table 中获取的行数
以下代码一次从 table 中读取 1,000 行并处理每一行
my $sth = $dbh->prepare("SELECT * FROM table");
$sth->execute;
while ( my $chunk = $sth->fetchall_arrayref( undef, 1000 ) ) {
last unless @$chunk; # Empty array returned at end of table
for my $row ( @$chunk ) {
print format_row(@$row);
}
}
apparently all results from query is store in memory after execute() command
这是 mysql 客户端库的默认行为。您可以通过在数据库或语句句柄上使用 mysql_use_result attribute 来禁用它。
请注意,当所有行都流式传输到客户端代码时,您在 table 上的读锁将保持更长的时间。如果这可能是一个问题,您可能需要使用 SQL_BUFFER_RESULT.
在使用大表时,我使用动态构建的 SQL 语句构建数据包,例如
$sql = "SELECT * FROM table WHERE id>" . $lastid . " ORDER BY id LIMIT " . $packagesize
应用程序将根据它处理的每个包动态填写$lastid
。
如果 table
有一个 ID 字段 id
它也有一个建立在该字段上的索引,因此性能非常好。
它还通过每个查询之间的小休息来限制数据库负载。
我需要从 mysql table 获取所有数据。到目前为止我尝试过的是:
my $query = $connection->prepare("select * from table");
$query->execute();
while (my @row=$query->fetchrow_array)
{
print format_row(@row);
}
但总有一个但是...
Table 有大约 600M 行,显然所有查询结果都在 execute()
命令后存储在内存中。内存不足:(
我的问题是:
有没有办法使用 perl DBI 从 table 逐行获取数据?像这样:
my $query = $connection->prepare("select * from table");
while (my @row=$query->fetchrow_array)
{
#....do stuff
}
顺便说一句,分页速度很慢:/
fetchall_arrayref
方法有两个参数,第二个参数允许您限制一次从 table 中获取的行数
以下代码一次从 table 中读取 1,000 行并处理每一行
my $sth = $dbh->prepare("SELECT * FROM table");
$sth->execute;
while ( my $chunk = $sth->fetchall_arrayref( undef, 1000 ) ) {
last unless @$chunk; # Empty array returned at end of table
for my $row ( @$chunk ) {
print format_row(@$row);
}
}
apparently all results from query is store in memory after execute() command
这是 mysql 客户端库的默认行为。您可以通过在数据库或语句句柄上使用 mysql_use_result attribute 来禁用它。
请注意,当所有行都流式传输到客户端代码时,您在 table 上的读锁将保持更长的时间。如果这可能是一个问题,您可能需要使用 SQL_BUFFER_RESULT.
在使用大表时,我使用动态构建的 SQL 语句构建数据包,例如
$sql = "SELECT * FROM table WHERE id>" . $lastid . " ORDER BY id LIMIT " . $packagesize
应用程序将根据它处理的每个包动态填写$lastid
。
如果 table
有一个 ID 字段 id
它也有一个建立在该字段上的索引,因此性能非常好。
它还通过每个查询之间的小休息来限制数据库负载。