- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我想知道使用 Perl DBI 从 Oracle 数据库中提取任意大数据字段的最节省内存的方法。我知道要使用的方法是将数据库句柄上的“LongReadLen”属性设置为足够大的值。但是,我的应用程序需要提取几千条记录,因此任意执行此操作的内存效率极低。
doc建议预先进行查询以找到最大的潜在值,然后进行设置。
$dbh->{LongReadLen} = $dbh->selectrow_array(qq{
SELECT MAX(OCTET_LENGTH(long_column_name))
FROM table WHERE ...
});
$sth = $dbh->prepare(qq{
SELECT long_column_name, ... FROM table WHERE ...
});
然而,这仍然是低效的,因为外围数据并不能代表每条记录。最大值超过 MB,但平均记录小于 KB。我希望能够提取所有信息(即不截断),同时尽可能少地在未使用的缓冲区上浪费内存。
我考虑过的一种方法是将数据分成 block ,比如说一次 50 条记录,然后根据该 block 的最大记录长度设置 LongReadLen。另一种解决方法,可以但不必基于 block 的想法,是 fork 一个子进程,检索数据,然后杀死子进程(带走浪费的内存)。最美妙的事情是能够强制释放 DBI 缓冲区,但我认为这是不可能的。
有没有人成功解决过类似的问题?感谢您的帮助!
编辑
Perl v5.8.8,DBI v1.52
澄清一下:内存效率低下是因为在准备过程中将“LongReadLen”与 {ora_pers_lob => 1} 一起使用。使用此代码:
my $sql = "select myclob from my table where id = 68683";
my $dbh = DBI->connect( "dbi:Oracle:$db", $user, $pass ) or croak $DBI::errstr;
print "before";
readline( *STDIN );
$dbh->{'LongReadLen'} = 2 * 1024 * 1024;
my $sth = $dbh->prepare( $sql, {'ora_pers_lob' => 1} ) or croak $dbh->errstr;
$sth->execute() or croak( 'Cant execute_query '. $dbh->errstr . ' sql: ' . $sql );
my $row = $sth->fetchrow_hashref;
print "after";
readline( *STDIN );
“之前”的常驻内存使用量为 18MB,“之后”的使用量为 30MB。这对于大量查询来说是 Not Acceptable 。
最佳答案
您的列是否包含大数据 LOB(CLOB 或 BLOB)?如果是这样,您根本不需要使用 LongReadLen; DBD::Oracle 提供了一个 LOB 流接口(interface)。
你要做的是bind the param作为 ORA_CLOB
或 ORA_BLOB
类型,这将为您提供从查询返回的“LOB 定位器”,而不是 tex。然后你使用 ora_lob_read与 LOB 定位器一起获取数据。这是对我有用的代码示例:
sub read_lob {
my ( $dbh, $clob ) = @_;
my $BLOCK_SIZE = 16384;
my $out;
my $offset = 1;
while ( my $data = $dbh->ora_lob_read( $clob, $offset, $BLOCK_SIZE ) ) {
$out .= $data;
$offset += $BLOCK_SIZE;
}
return $out;
}
关于linux - LongReadLen 的 Perl DBI 替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8425465/
如何更改此脚本才能截断 BLOB 输出? #!/usr/bin/env perl use warnings; use strict; use utf8; use 5.10.1; use DBI; my
使用DBD::mysql 时具有属性LongReadLen 和LongTruncOk作为 Perl5 数据库接口(interface) (DBI) 的驱动程序有什么意义?我没有在 DBD::mysql
我想知道使用 Perl DBI 从 Oracle 数据库中提取任意大数据字段的最节省内存的方法。我知道要使用的方法是将数据库句柄上的“LongReadLen”属性设置为足够大的值。但是,我的应用程序需
我是一名优秀的程序员,十分优秀!