【问题标题】:Python + MongoDB - Cursor iteration too slowPython + MongoDB - 光标迭代太慢
【发布时间】:2011-07-25 17:15:42
【问题描述】:

我实际上正在从事一个搜索引擎项目。我们正在使用 python + mongoDb。

在对 mongo db 执行 find() 命令后,我有一个 pymongo 光标。 pymongo 游标有大约 20k 个结果。

我注意到 pymongo 光标上的迭代与普通迭代相比非常慢,例如相同大小的列表。

我做了一个小基准测试:

  • 20k 字符串列表的迭代:0.001492 秒
  • 在 pymongo 游标上迭代,结果为 20k:1.445343 秒

差别真的很大。这么多结果可能不是问题,但如果我有数百万个结果,时间将是不可接受的。

有没有人知道为什么 pymongo 游标太慢而无法迭代? 知道如何在更短的时间内迭代光标吗?

一些额外的信息:

  • Python v2.6
  • PyMongo v1.9
  • MongoDB v1.6 32 位

【问题讨论】:

  • 你能改变你的应用程序的逻辑——例如使用.skip().limit()——这样你就不会返回这么大的结果集吗?
  • 事实上,20k 只占文档总量的一小部分。我认为这不是一个可扩展的解决方案,因为我希望得到比 20k 更多的结果。无论如何谢谢=)。
  • 您的每个结果都是裸字符串吗?
  • 没有。我有一个类似的文档: {"something": "string", "other": [{"key", "value"},{"key2": "value2"},...], "something_more":整数}。无论如何,我最近尝试使用一组裸字符串文档,将其链接:{“something”:“string”},迭代时间的差异是相同的。 :S

标签: python mongodb performance iteration database-cursor


【解决方案1】:

请记住,pymongo 驱动程序不会一次性返回所有 20k 结果。当您迭代时,它正在对 mongodb 后端进行网络调用以获取更多项目。当然它不会像字符串列表那么快。但是,我建议尝试调整光标 batch_size as outlined in the api docs

【讨论】:

  • 我也注意到了,当然时间取决于你在 mongo 和脚本之间传输的数据量。这就是为什么我更改了查询,对迭代中不需要的键添加了限制,例如:.find({},{"key1":0, "key3":0})。这大大减少了时间。
  • 这两个项目都有意义 - 批处理控制每次从 MongoDB 获取时发送多少项目。当然,将您返回的字段仅限于您正在使用的字段会减少必要的网络流量。
  • 不是特别 - 这是通过网络传送 20k 文件的本质。
  • @Brendan。我使用 C++ 驱动程序而不是 python 驱动程序进行了一些测试,使用相同的查询,性能提高了 3 倍。我认为考虑到这一点很重要。谢谢!
  • 答案中的链接不起作用..请更新它。
【解决方案2】:

您没有提供有关整体文档大小的任何信息。获取如此数量的文档需要网络流量和数据库服务器上的 IO。

即使在具有热缓存的“热”状态下,性能仍保持“差”?您可以使用“mongosniff”来检查“wire”活动,并使用“iostat”等系统工具来监控服务器上的磁盘活动。此外,“mongostat”提供了一堆有价值的信息”。

【讨论】:

  • 如果您不再称所有人为“白痴”,也许人们会停止对您投反对票。请注意你的举止。我不止一次将您推荐给FAQ,以阅读有关可接受行为的部分;辱骂不是这种行为的一部分。
【解决方案3】:

默认光标大小为 4MB,最大可达到 16MB。您可以尝试增加光标大小,直到达到该限制,然后查看是否有所改进,但这也取决于您的网络可以处理什么。

【讨论】:

    【解决方案4】:

    您的 pymongo 安装是否使用包含的 C extensions

    >>> import pymongo
    >>> pymongo.has_c()
    True
    

    我上周大部分时间都在尝试调试一个中等大小的查询和相应的处理,它需要 20 秒才能运行。一旦安装了 C 扩展,整个相同的过程大约需要一秒钟。

    要在 Debian 中安装 C 扩展,请在运行 easy install 之前安装 python 开发头文件。就我而言,我还必须删除旧版本的 pymongo。请注意,这将从 C 编译二进制文件,因此您需要所有常用工具。 (海合会等)

    # on ubuntu with pip
    $ sudo pip uninstall pymongo
    $ sudo apt-get install python-dev build-essential
    $ sudo pip install pymongo
    

    【讨论】:

    • 这彻底颠覆了我的表现。我有一个查询需要 5 秒,现在需要 0.01!我已经添加了在 ubuntu 上安装的步骤
    • 我知道这已经很老了,但是你怎么能在最新的 OS X 上安装它呢?
    猜你喜欢
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多