【问题标题】:MongoDB - Querying performance for over 10 million recordsMongoDB - 超过 1000 万条记录的查询性能
【发布时间】:2014-07-09 19:49:30
【问题描述】:

首先:我已经根据MongoDB查询性能看了很多帖子,但没有找到好的解决方案。

在集合内部,文档结构如下:

{
    "_id" : ObjectId("535c4f1984af556ae798d629"),
    "point" : [
        -4.372925494081455,
        41.367710205649544
    ],
    "location" : [
        {
            "x" : -7.87297955453618,
            "y" : 73.3680160842939
        },
        {
            "x" : -5.87287143362673,
            "y" : 73.3674043270052
        }
    ],
    "timestamp" : NumberLong("1781389600000")
}

我的收藏已经有了索引:

db.collection.ensureIndex({timestamp:-1})

查询如下:

db.collection.find({ "timestamp" : { "$gte" : 1380520800000 , "$lte" : 1380546000000}})

尽管如此,响应时间太长了,大约 20 - 30 秒(这个时间取决于指定的查询参数)

任何帮助都是有用的!

提前致谢。

编辑:我更改了查找参数,将它们替换为真实数据。

上述查询耗时46秒,这是explain()函数给出的信息:

{
    "cursor" : "BtreeCursor timestamp_1",
    "isMultiKey" : false,
    "n" : 124494,
    "nscannedObjects" : 124494,
    "nscanned" : 124494,
    "nscannedObjectsAllPlans" : 124494,
    "nscannedAllPlans" : 124494,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 45,
    "nChunkSkips" : 0,
    "millis" : 46338,
    "indexBounds" : {
        "timestamp" : [
            [
                1380520800000,
                1380558200000
            ]
        ]
    },
    "server" : "ip-XXXXXXXX:27017"
}

【问题讨论】:

  • 如果您的意图是地理位置查询,您可能需要考虑使用不同的文档结构。但除此之外,您的查询看起来比实际更具理论性(因为时间戳值显然不在您指定的范围内)并且理论问题很少得到有意义的答案。 “1000 万条记录”查询中还涉及很多变量,除非您可以更具体,否则这些变量的覆盖范围非常广泛。请尝试并提出一个非常具体的案例。
  • 我同意您的搜索本身获得了 124K 记录,这并没有太大的改进空间

标签: mongodb performance indexing nosql


【解决方案1】:

解释输出再理想不过了。您通过索引 (nscanned) 找到了 124,494 个文档,它们都是有效结果,因此它们都被返回了 (n)。它仍然不是仅索引查询,因为边界不是在特定文档中找到的精确值。

这个查询有点慢的原因可能是它返回的数据量很大。您找到的所有文档都必须从硬盘读取(当集合是冷的时)、扫描、序列化、通过网络发送到客户端并由客户端反序列化。

您的用例真的需要这么多数据吗?如果答案是肯定的,那么响应性真的很重要吗?我不知道你真正想要创建什么样的应用程序,但我猜测你的应用程序是三个用例之一:

  1. 您希望以某种报告的形式显示所有数据。这意味着输出将是一个巨大的列表,用户必须滚动浏览。在这种情况下,我建议使用分页。仅在一个屏幕上加载尽可能多的数据并提供next 和previous 按钮。 MongoDB 分页可以使用游标方法.limit(n) 和.skip(n) 完成。
  2. 以上,但它是某种离线报告,用户可以下载然后使用各种数据挖掘工具进行检查。在这种情况下,初始加载时间是可以接受的,因为用户会花一些时间处理他们收到的数据。
  3. 您不想向用户显示所有原始数据,而是对其进行处理并以某种聚合方式(如统计数据或图表)呈现。在这种情况下,您可能已经使用聚合框架在数据库上完成了所有这些工作。

【讨论】:

  • @user1503117 您如何使用分页并使查询更快?你能解释一下吗?
  • 我必须比较来自 mongo 和 mysql 的数据。这两个数据大约有 500,000 行,我使用 python 进行实际比较。 mongo 集合中的数据现在增加了很多,即使有索引,按时间戳选择也需要大约 10 分钟。有什么办法可以减少这个时间?
  • 尝试分片来提高效率,肯定会提高。
猜你喜欢
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-11
  • 2012-01-09
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
相关资源
最近更新 更多