【问题标题】:Query performance of a range query with date field带日期字段的范围查询的查询性能
【发布时间】:2020-06-20 18:30:19
【问题描述】:

我正在寻找查询的性能优化。我的目标是找到给定日期范围内的所有文档。集合相当大,它有超过 600 万份文档。所以查询如下:

db.collection.find({
    createdAt: {
        $gte: new Date('2018-06-19'), 
        $lt: new Date('2018-06-22')
    }
})

运行时间超过 10 分钟。有没有办法利用日期排序的事实?我的意思是文档是在创建时插入的,因此最后一个文档之后落入该范围的每个文档都将超出范围,但 mongo 可能不知道并寻找那些日期已经超出范围的文档??

【问题讨论】:

  • createdAt 是否已编入索引?是否可以投影选定的字段而不是获取整个文档?
  • 它没有被索引,向它添加 idex 是否需要特别小心,而不是让数据库过载这么多项目?我知道我可以添加索引、减少字段等,但我想知道具体的日期范围排序顺序

标签: mongodb indexing mongodb-query query-performance


【解决方案1】:

MongoDB 无法利用“事实”,因为它不知道存储了哪些二进制文档。

如果按非索引字段搜索,Mongodb 执行COLLSCAN(解释为here

索引:

从 v4.2 开始,MongoDB 使用优化的构建过程,仅在构建过程的开始和结束时持有排他锁。

v4.2之前需要指定background选项

db.collection.createIndex({createdAt:1}, {background:true})

https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#options-for-all-index-types

【讨论】:

    【解决方案2】:

    应用程序及其用户正在寻找具有几百万个文档的集合在几百毫秒(而不是 10 分钟)内的查询性能。索引用于使这些查询快速运行。

    通过在查找查询过滤器的日期字段上创建单个字段索引,可以使上述范围查询快速运行。索引存储索引键字段值和集合中文档的地址 - 这是少量数据。对于典型的集合、查询和索引,集合的数据和索引需要在内存(称为工作集)中可用(或适合)才能有效使用。运行查询时,根据过滤条件访问索引,然后访问相应的文档。

    如果不使用索引,则无法使查询运行得更快,因为有数百万个文档(请注意,对于数千个文档可能无关紧要)。这可以在 dev 环境中得到实际证明,该环境具有几百万个文档的样本集、查询过滤器字段上的索引和测试运行。

    用于执行此测试的工具正在生成query plan using the explainexplain method 具有“executionStats”模式,它提供了诸如使用的索引(如果有)、运行查询的时间、访问的索引键、返回的文档数、查询执行的各个阶段等详细信息。计划阶段将告诉查询是否使用了索引。通常,使用索引运行的查询将显示索引扫描 (IXSCAN),如果不使用索引,则将显示集合扫描 (COLLSCAN)。

    创建的索引也可以用于其他查询(如果适用)以及排序操作。此外,索引可以是复合索引(使用多个字段)并且可以与其他查询一起使用。

    另外,请参阅FAQ: Indexes 了解更多信息。由于您已经拥有大量收藏,请参阅Index Builds on Populated Collections 以了解有关注意事项。

    db.collection.stats() 命令对于查找集合的大小和索引很有用。

    除了索引之外,仅对必填字段进行投影也会影响您的查询性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多