DBI的fetchall_hashref和fetchall_arrayref之间的性能差异是什么?

时间:2010-02-23 04:49:38

标签: performance perl dbi

我正在编写一些Perl脚本来处理两个PostgreSQL数据库中的大量数据(总共大约4200万行,但不会在一次命中中完成)。

对于我的一些查询,使用fetchall_hashref是合理的,因为我有合成密钥。但是,在其他情况下,我将使用三列数组作为唯一键。

这让我想知道fetchall_arrayreffetchall_hashref之间的效果差异。我知道在这两种情况下,一切都进入内存,因此选择几GB的数据可能不是一个好主意,但除此之外,在性能方面,文档中似乎没有什么指导。

我的谷歌搜索没有成功,所以如果有人能指出我的一些一般表现研究的方向,我将不胜感激。

(我知道我可以自己对此进行基准测试,但不幸的是,出于开发目的,我无法访问具有相同硬件生产的机器,这就是为什么我正在寻找一般指导方针甚至是最佳实践。)

2 个答案:

答案 0 :(得分:5)

获取方法之间的大多数选择取决于您希望数据最终的格式以及您希望DBI为您做多少工作。

我的回忆是,使用fetchrow_arrayref进行迭代并使用bind_columns是读取返回数据的最快(最少DBI开销)方式。

答案 1 :(得分:3)

第一个问题是,真的是否需要首先使用fetchall。如果你一次不需要内存中的所有4200万行,那就不要一次全部读取它们!正如已经指出的那样,bind_columnsfetchrow_arrayref通常是可行的方式。

假设确实需要fetchall,我的直觉是fetchall_arrayref稍微快一点,因为数组是一个更简单的数据结构,不需要计算插入的键的哈希值,但是数据库读取时间的节省会相形见绌,因此不太可能显着。

然而,内存要求完全是另一回事。 fetchall_hashref返回的结构是id => row的哈希值,每行表示为field name => field value的哈希值。如果你获得了4200万行,这意味着你的4200万个散列键中的每一个都重复了你的字段名列表...这将需要比{{返回的数组数组数组更多的内存来存储。 1}}。 (除非DBI对fetchall_arrayref做了一些魔术来优化tie结构,我猜想。)