【问题标题】:Indexes for mongodbMongoDB 的索引
【发布时间】:2013-07-09 14:03:40
【问题描述】:

我有一个用于餐馆的 mongo db 集合。 例如 {_id:uniquemongoid, 排名:3, 城市:“柏林” }

  1. 餐厅按城市列出并按等级(整数)排序​​ - 我应该创建城市和等级索引,还是城市/等级复合索引? (我按城市查询,按排名排序)

  2. 此外,还有几个带有布尔值的字段,例如{ hasParking:true, familyFriendly:true } - 我应该创建索引来加快对这些过滤器的查询吗?复合索引?我不清楚是否应该创建复合索引,因为查询只能有一个布尔集或多个布尔集。

【问题讨论】:

  • 这完全取决于您拥有多少数据以及您的查询是什么。
  • 请注意,您可以使用explain() method of cursor 来检查用于完成查询的索引。因此,当您不确定给定索引是否有助于特定查询时,您可以尝试并检查。
  • 我的同事就此发表了演讲:youtube.com/watch?v=AVNjqgf7zNw 他以 mysql 为例,但原理相同。也许它会帮助您设计索引。

标签: performance mongodb indexing


【解决方案1】:

确定是否需要索引的最佳方法是使用“explain()”对其进行基准测试。

至于您建议的索引:

  1. 您将需要城市/等级复合索引。 MongoDB 中的索引只能用于从左到右(目前),因此对“城市”进行相等搜索,然后按“排名”对结果进行排序将意味着 { city: 1, rank: -1 } 索引效果最好。

  2. 布尔字段上的索引通常不是很有用,因为平均而言 MongoDB 仍需要访问一半的文档。在按城市进行选择之后(希望是限制!)为 hasParking 等做一个额外的过滤器不会使 MongoDB 同时使用城市/排名和 hasParking 索引。 MongoDB 每次查询只能使用一个索引。

【讨论】:

  • for 2) 您是否同意 Abhishek Kumar 创建一个包含所有布尔值的字段并在其上创建索引?
  • 不,因为索引元素的数量仍然非常少。
【解决方案2】:

1) 创建索引 { restaurant:1, rank: 1} 这将服务于您的目的。

您将避免 2 个索引

2) 创建一个如下格式的文档,你可以查询任何你想要的字段。

{
    info: [{hasParking:true}, {familyFriendly:true}],
    _id:
    rank:
    city:
}
db.restaurants.ensureIndex({info : 1});
db.restaurants.find({ info :{ hasParking:true}})
  • 注意 MongoDB 不会对同一个查询使用两个索引($or 查询除外)。因此,在 (2) 的情况下,如果您想在 (1) 查询上添加添加过滤器,则此 (2) 选项将不起作用。我不确定您的 (2) 要求,因此发布此解决方案。

【讨论】:

  • 查询将有城市、排名、布尔值我应该用它们创建一个索引吗?只有城市会有更多的查询,我应该创建 2 个索引吗?
  • 我不会推荐你使用{ city:1, rank:-1, info:1 },因为索引会很大。我也怀疑这个索引是否可以有效地用于获取排序的结果数据(检查explain() 中的scanAndOrder)。关于第二个查询,如果我理解正确,它将不起作用,因为 mongo 永远不会为单个查询使用两个索引,即 { info:1 }{ city:1, rank:-1 } 如果您对索引大小感到满意,则可以使用第一种方法。
  • 我将有大约 10k 家餐厅,我想我现在会采用第一种方法。但是由于我们经常更新(排名),这可能会成为一个问题(除了索引大小),对吧?
  • 每次因为排名的更新而更新都会引起一次索引的更新。对于 10k,不会有任何问题,假设索引将始终适合 RAM。
  • 谢谢。也许您想将 1) 更新为排名:-1 和 2) 第一种方法
猜你喜欢
  • 2012-09-19
  • 2012-04-29
  • 1970-01-01
  • 2010-12-17
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多