【问题标题】:CouchDB-Python query performanceCouchDB-Python 查询性能
【发布时间】:2012-08-22 19:46:59
【问题描述】:

我有几个 CouchDB 数据库。最大的是大约 600k 个文档,我发现查询时间过长(几个小时或更长时间)。数据库不经常更新(大约一个月一次),只涉及添加新文档,从不更新现有文档。

查询的类型为:查找所有包含key1='a' 或多个键的文档:key1='a', key2='b'...

我认为永久视图在这里并不实用,因此一直在使用 CouchDB-Python 的“查询”方法。

我尝试了几种方法,但我不确定哪种方法最有效,或者为什么。

方法一: 地图功能是:

    map_fun = '''function(doc){
        if(doc.key1=='a'){
            emit(doc.A, [doc.B, doc.C,doc.D,doc.E]);
        }
    }'''

Python 查询是: 结果 = ui.db.query(map_fun, key2=user)

然后对 results.rows 进行一些操作。这占用的时间最多。

“results.rows”大约需要一个小时才能返回。如果我将 key2 更改为其他内容,它会在大约 5 秒内返回。如果我重复原始用户,它也很快。

但有时我需要查询更多的键,所以我尝试:

    map_fun = '''function(doc){
        if(doc.key1=='a' && doc.key2=user && doc.key3='something else' && etc.){
            emit(doc.A, [doc.B, doc.C,doc.D,doc.E]);
        }
    }'''

并使用 python 查询:

结果 = ui.db.query(map_fun) 然后对 results.rows 进行一些操作

第一次查询需要很长时间。当我更改 key2 时,又需要很长时间。如果 我将 key2 改回原始数据,花费相同的时间。 (也就是说,似乎没有任何东西被缓存,B-tree'ed 或其他)。

所以我的问题是:在 couchdb-python 中进行查询的最有效方法是什么,其中查询是临时的并且涉及搜索条件的多个键?

UI 是基于 QT 的,在底层使用 PyQt。

【问题讨论】:

    标签: python performance couchdb


    【解决方案1】:

    couchdb-python db.query() 方法有两个注意事项:

    1. 它执行temporary view。这意味着代码流处理将被阻止,直到所有文档都由该视图处理。每次通话都会一次又一次地发生这种情况。尝试保存视图并改用db.view() 方法来按需获取结果并进行增量索引更新。

    2. 无论结果有多大,它都会读取整个结果。 db.query() 和 db.view() 方法都不是惰性的,所以如果视图结果是 100 MB JSON 对象,您必须在以某种方式使用它们之前获取所有这些数据。要以更优化内存的方式查询数据,请尝试应用补丁以具有 db.iterview() 方法 - 它允许您以分页样式获取数据。

    【讨论】:

    • 感谢 Kxepal。使用 iterview 还可以让我为用户提供一个完成百分比表。他们会更宽容地使用界面,如果他们知道它正在做某事,以及需要多长时间。
    【解决方案2】:

    我认为解决您的问题的方法是为您正在搜索的键创建索引。这就是你所说的永久视图。

    注意基于 B-tree 的表中 map/reduce 和 SQL 查询之间的区别:

    • 简单的 SQL 查询搜索键(如果您有索引)遍历 B+-树中从根到叶的单个路径,
    • map 函数读取所有元素,如果它发出小结果则事件。

    你正在做的是每个查询

    1. 阅读每个文档(大部分成本)和
    2. 在发出的结果中搜索一个键(在 B 树中快速搜索)。

    而且我认为您的解决方案在设计上必须很慢。

    如果您重新设计数据库结构以使永久视图变得实用,则 (1.) 将执行一次,并且对于每个查询仅执行 (2.)。添加到数据库后,视图将读取每个文档,并且查询将在存储发出结果的 B-tree 中搜索。如果发出的集合小于总文档数,则查询搜索较小的结构,您将获得优于 SQL 数据库的优势。

    临时视图的效率远低于永久视图,并且仅用于开发。 CouchDB 旨在使用永久视图。为了使 map/reduce 高效,必须实现缓存或使视图永久化。我不熟悉 CouchDB 实现的细节,可能由于一些缓存,使用不同键的第二个查询更快。如果由于某种原因您必须使用临时视图,那么 CouchDB 可能是一个错误,您应该考虑为 MongoDB 等在线查询创建和优化 DBMS。

    【讨论】:

      猜你喜欢
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多