在多个字段上创建MongoDB复合索引,有些重叠吗?

时间:2012-03-02 22:18:40

标签: ruby-on-rails mongodb mongoid

我是MongoDB的新手,并尝试确保设置正确的索引。我在这里看到了关于复合索引的类似问题,但没有一个完全覆盖我所处的情况。

注意:我正在使用Rails 3.2和Mongoid。

我有一组事件,这些事件总是会在日期进行排序(并经常被搜索),但通常还有另一个参数。例如,我可能想要查找在特定日期范围内与特定类别集匹配的事件;或者我可能想要在特定日期范围内找到与特定人匹配的事件。搜索类型为:

  1. 始终按日期(或至少按日期排序)
  2. 通常按类别
  3. 有时候还会[人,地点或关键词]
  4. 我提出的第一个解决方案是多个复合键,它们都以日期和类别开头,如下所示:

    class Event
    ...
    
    index ([
        [:date, Mongo::DESCENDING], 
        [:category_id, Mongo::ASCENDING]
        ["people.person_id", Mongo::ASCENDING]
      ])
    index ([
        [:date, Mongo::DESCENDING], 
        [:category_id, Mongo::ASCENDING]
        [:venue_id, Mongo::ASCENDING]
      ])
    index ([
        [:date, Mongo::DESCENDING], 
        [:category_id, Mongo::ASCENDING]
        [:keywords, Mongo::ASCENDING]
      ])
    

    但是对于我来说,保持重叠“date + category_id”索引似乎有点滑稽,以及当我搜索category_id时的情况呢?

    更新: dcrosta询问运行的查询类型以及频率。如果不确切知道,我可以猜测它看起来像下面这样:

    非常频繁:

    • 按日期
    • 按日期+类别
    • 按日期+关键字
    • 按日期+类别+关键字

    有点频繁:

    • 按日期+人
    • by date + venue

    不太频繁:

    • 按日期+类别+地点
    • 按日期+类别+人

1 个答案:

答案 0 :(得分:3)

好的,鉴于这些查询,这里是我要创建的索引:

db.events.createIndex({date: 1, category: 1})
db.events.createIndex({date: 1, keyword: 1})

这些查询中的任何一个都只能用于date的查询,并且可以用于date + category + keyword。在最后一种情况下选择哪一个将取决于两个字段的选择性和所讨论的特定查询。

您可能还需要date上的索引,这将作为剩余查询的全能。这是否会对数据有多大帮助取决于数据的数量以及确切地说是什么?有些频繁"完全是指。

更一般地说,并解决您的初始问题,MongoDB中的索引(如任何数据库)将提高查询的性能(对于那些匹配的查询),但代价是稍微降低更新/插入/删除的性能(因为索引必须与底层数据一起修改)。我的方法是为这些查询构建索引,我知道这些查询要么非常昂贵,要么非常频繁,然后使用实际的负载分布(即查询和更新/插入/删除的实际数量和频率)进行测试,以查看其他内容查询比您预期的更昂贵。您可以使用database profiler来帮助收集此信息,可能使用Professor(#shamelessplug)等工具来帮助理解结果。