2012-02-13 44 views
0

我想遍历不适合内存的大表。Perl中的表格光标

在Java中,我可以使用游标并根据需要加载内容并且不会溢出内存。我如何对Perl做同样的事情?

我正在使用的数据库是PostgreSQL和DBI。

+1

什么数据库?什么perl模块?什么代码? – 2012-02-13 20:23:22

+0

@BrianRoach对不起,我是Perl新手。 PostgreSQL和DBI。 – 2012-02-13 20:24:54

回答

3

我使用PostgreSQL数据库PostgreSQL的光标。

my $sql = "SOME QUERY HERE"; 
$dbh->do("DECLARE csr CURSOR WITH HOLD FOR $sql"); 
my $sth = $dbh->prepare("fetch 100 from csr"); 
$sth->execute; 

while(my $ref = $sth->fetchrow_hashref()) {  
    //... - processing here 
    if ($count % 100 == 0){    
     $sth->execute; 
    } 
} 
3

只需在PostgreSQL中使用数据库游标即可。从manual一个例子:

BEGIN WORK; 

-- Set up a cursor: 
DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films; 

-- Fetch the first 5 rows in the cursor liahona: 
FETCH FORWARD 5 FROM liahona; 

code |   title   | did | date_prod | kind | len 
-------+-------------------------+-----+------------+----------+------- 
BL101 | The Third Man   | 101 | 1949-12-23 | Drama | 01:44 
BL102 | The African Queen  | 101 | 1951-08-11 | Romantic | 01:43 
JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25 
P_301 | Vertigo     | 103 | 1958-11-14 | Action | 02:08 
P_302 | Becket     | 103 | 1964-02-03 | Drama | 02:28 

-- Fetch the previous row: 
FETCH PRIOR FROM liahona; 

code | title | did | date_prod | kind | len 
-------+---------+-----+------------+--------+------- 
P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08 

-- Close the cursor and end the transaction: 
CLOSE liahona; 
COMMIT WORK; 
0

看DBD :: PG docs为例。

在while()循环中使用DBI fetchrow_ *函数来实现较小的内存分配,避免fetchall_ *。

  • LongReadLen - '长' 类型字段的最大长度(LONG,BLOB,CLOB,MEMO,等)
  • RowCacheSize的(在DBD不用于:与存储器使用

    其他数据库选项: :Pg) - 提示驱动程序指出应用程序希望驱动程序用于未来“SELECT”语句的本地行缓存的大小。

1

出了什么问题:

my $s = $h->prepare(select ...); 
$s->execute; 
while(my $row = $fetchrow_arrayref) { 
    ; # do something 
} 
+0

查询的结果将转到内存。如果结果大于内存,则出现SWAP并且速度慢。 – 2012-02-14 13:25:37

+0

不是从DBI的角度来看,它不是。这从DBD一次获取一行。如果DBD选择一次返回多于一行,这是一个不同的问题,并且我期望DBD或客户端库中有某些内容,它依赖于允许您修改该行为。 – bohica 2012-02-14 16:16:05

+2

libpq本身将始终将整个结果集缓冲到内存中:除了明确使用游标之外,没有办法在DBI中对其进行整理。 – araqnid 2012-02-14 17:55:14