【问题标题】:MongoDB Many Indexes vs. Single Index on array of Sub-Documents?MongoDB子文档数组上的许多索引与单个索引?
【发布时间】:2011-10-23 20:53:50
【问题描述】:

想知道哪种技术可以更有效地索引我需要跟踪的文档的各种时间戳,请记住我的应用程序在编写时相当繁重,但在读取时足够繁重,没有索引,查询也是慢。

最好为每个时间戳设置一个字段,并对每个字段进行索引,还是将时间戳及其关联类型存储在一个数组字段中,然后对该数组的每个字段进行索引?

第一个选项,单独的字段,每个字段都有一个索引:

{
    "_id" : "...",
    "Field1.Timestamp" : '2011-01-01 01:00.000',
    "Field2.Timestamp" : '2011-01-01 01:00.000',
    "Field3.Timestamp" : '2011-01-01 01:00.000',
    "Field4.Timestamp" : '2011-01-01 01:00.000',
    "Field5.Timestamp" : '2011-01-01 01:00.000',
    "Field6.Timestamp" : '2011-01-01 01:00.000',
    "Field7.Timestamp" : '2011-01-01 01:00.000',
    "Field8.Timestamp" : '2011-01-01 01:00.000',
    "Field9.Timestamp" : '2011-01-01 01:00.000',
}

db.mycollection.ensureIndex({ "Field1.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field2.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field3.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field4.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field5.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field6.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field7.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field8.Timestamp" : 1 });
db.mycollection.ensureIndex({ "Field9.Timestamp" : 1 });

然后是时间戳及其状态的数组,只有一个索引

{
    "_id" : "...",
    "Timestamps" : [
        { "Type" : "Field1", "Timestamp" : '2011-01-01  01:00.000' },
        { "Type" : "Field2", "Timestamp" : '2011-01-01  01:00.000' },
        { "Type" : "Field3", "Timestamp" : '2011-01-01  01:00.000' },
        { "Type" : "Field4", "Timestamp" : '2011-01-01  01:00.000' },
        { "Type" : "Field5", "Timestamp" : '2011-01-01  01:00.000' },
        { "Type" : "Field6", "Timestamp" : '2011-01-01  01:00.000' },
        { "Type" : "Field7", "Timestamp" : '2011-01-01  01:00.000' },
        { "Type" : "Field8", "Timestamp" : '2011-01-01  01:00.000' },
        { "Type" : "Field9", "Timestamp" : '2011-01-01  01:00.000' },
    ]
}

db.mycollection.ensureIndex({ "Timestamps.Type" : 1, "Timestamps.Timestamp" : 1 });

我在这里是不是太离谱了?或者哪种方式更好

【问题讨论】:

  • 您的查询是什么样的?
  • 查询在 $LT 比较中使用时间戳字段: { "Field1Timetamp" : { $LT : "2011-01-01 01:00.000" }, "BatchExpires" : { $LT : " 2011-01-01 01:00.000" }, "Prioritized" : true } 索引也将包括其他两个字段,但为简单起见,我将它们省略了,因为它们中没有几个(只会有一个 BatchExpires 和一个 Prioritized 字段)
  • 我的想法是,子文档数组上的 2 个索引是否比不在数组中的字段上的 9 或 10 个索引更有效...
  • 我认为更少的索引可能是更好的方法,但我不能肯定地说,如果关键的话,可能值得对两种方式进行基准测试。

标签: mongodb indexing mongodb-.net-driver


【解决方案1】:

这基本上归结为如果 10 个大小为 N 的索引比一个大小为 N * 10 的索引更有效。如果你纯粹看读取,那么单独的索引应该总是更快。相关的 b-tree walks 将检查较小的键集等。

有几点需要考虑:

  • 数组字段的索引基本上是单独索引每个数组元素。因此,在 b-tree walk 期间,查找开销最多会增加 1-2 个额外步骤,这对性能的影响可以忽略不计。换句话说,它们几乎一样快。
  • 拥有 10 个索引可能意味着每次更新/插入都需要更新多个索引(取决于您的索引是否共享一个字段或一次更新多个时间戳)。这是一个重要的性能考虑因素。
  • 使用数组索引可以更轻松地添加其他时间戳(例如 Timestamp10)。
  • 每个数据库可以使用的命名空间数量有限制 (24k),每个索引占用一个。如果您为每个字段创建单独的索引,这可能会成为问题。
  • 最重要的是,数组索引更加简单明了,可以简化您的代码,从而简化可维护性。鉴于性能差异有限,我想说这是在这里使用数组索引的最强烈动机。

【讨论】:

  • 所以您建议对于 UPDATE/INSERT,拥有一个索引应该比 10 个单独的索引快很多?我不确定如果它是被索引的对象数组,更新索引是否有更多开销......我真的不应该说超过 20 个需要索引的字段,但这似乎很多要索引的字段...
  • 如果替代方案意味着必须更新超过 1 个索引,则速度会更快。数组索引的处理方式与任何其他索引没有区别。数组中的每个值都被单独索引。
猜你喜欢
  • 2017-01-11
  • 2018-10-27
  • 1970-01-01
  • 2015-03-26
  • 2016-03-15
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
相关资源
最近更新 更多