从PostgreSQL复制数据到CouchDB

4

我有一个简单的PHP脚本:

$cc = new couchClient('http://localhost:5984', 'posts_votes');
for ($i = 0; $i < 107000000; $i += 100000) {
    // Usage of dibi database layer
    $data = dibi::select('*')->from('posts_votes')
        ->offset($i)
        ->limit(100000);
    foreach ($data as $n => $row) {
        $doc = new stdClass();
        $doc->post_id = $row->post_id;
        $doc->date = $row->date->format('Y-m-d H:i:s');
        $doc->upvotes = $row->upvotes;

        $cc->storeDoc($doc);
        if (($i+$n) % 1000 == 0) {
            echo ($i+$n).'...';
        }
    }
}

但这个脚本能够在没有Apache的情况下直接通过PHP解释器运行,每分钟大约复制8500条记录,这在需要复制大约100000000条记录时并不快。

有没有更快的方法?


那个dibi类是什么?看起来很整洁。 - Denis de Bernardy
@Denis 它是一个轻量级的数据库层 - http://dibiphp.com/ 不幸的是,目前没有完整的英文文档和教程等。 - Radek Simko
CouchDB不需要API包装器或“数据库层”。实际上,这些对CouchDB用户的影响更多是负面的而不是积极的。 - fiatjaf
3个回答

2

请使用storeDocs()方法而不是storeDoc()方法。 storeDocs(复数形式)将使用CouchDB的_bulk_docs API,速度更快。

也许您可以尝试实验找到最佳批处理大小。


根据内存,我选择了1000作为批处理大小。它会更快。 - Radek Simko
太棒了!如果你需要更多的提升,下一步就是使用线程或其他技术并行执行所有操作。这将再次为您提供类似的性能提升,并且您将接近CouchDB主机的硬件速度。(个人而言,我不会进行大量并行导入,因为它不值得为仅导入一次而调试,但这是一个很好的选择要知道!) - JasonSmith

2

以下是guide.couchdb.org关于批量插入的摘录:

通过HTTP将数据导入CouchDB的最快模式是使用_bulk_docs端点。批量文档API接受单个POST请求中的一组文档,并在单个索引操作中将它们全部存储到CouchDB中。

当您使用脚本语言导入数据集时,应使用批量文档API。它可以比单个批量更新快10到100倍,并且从大多数语言中使用起来同样容易。


1
但是这个脚本每分钟能够复制大约8500条记录。问题的一部分可能是在处理数据之前每次都要将100k行数据读入内存中。这可能是那些情况下,使用老式的pdo会更好的原因之一。
1. 为“select post_id, date, upvotes from posts_votes”创建并执行PDO语句(可选带有限制和偏移量)。 2. 使用:“while ($row = $stmt->fetch(DO::FETCH_OBJ))”
这样你每次只会创建一个对象。
然而,更快的方法可能是从psql中构建一个巨大的couchdb语句,并使用输出来批量加载couchdb中的内容。我不确定精确的couch语法,但以下是一个基础,可以帮助你开始:
select string_agg('{' ||
         'post_id: ' || post_id || ',' ||
         'date: ' || date::timestamp::text || ',' ||
         'upvotes: ' || upvotes ||
       '}', ',
')
from post_votes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接