MongoDB + C#:未选择/使用 GUID 字段上的复合索引
Posted
技术标签:
【中文标题】MongoDB + C#:未选择/使用 GUID 字段上的复合索引【英文标题】:MongoDB + C#: Compound Indexes on GUID fields not being chosen/used 【发布时间】:2015-08-30 13:47:56 【问题描述】:在了解了有关索引如何在 MongDB 上工作的更多信息后,我决定改进一个查询,该查询在几个月内将在我目前正在处理的项目中非常有用。基本上集合有这样的结构:
_id: UUID("0f8fad5b-d9cb-469f-a165-70867728950e"),
Title: "ABC",
BookId: UUID("7c9e6679-7425-40de-944b-e07fc1f90ae7"),
UserId: UUID("7c9e6579-7425-40de-944b-e07fc1f90az9"),
ModificationDate: ISODATE(...),
...
...
查询主要有以下两种格式:
该应用仅使用 BookId 和 UserId 进行过滤
db.userBooks.find(BookId: UUID("7c9e6679-7425-40de-944b-e07fc1f90ae7"), UserId: UUID("7c9e6579-7425-40de-944b-e07fc1f90az9"));
应用现在正在使用 BookId、UserId 和 ModificationDate 进行过滤
db.userBooks.find(BookId: UUID("7c9e6679-7425-40de-944b-e07fc1f90ae7"), UserId: UUID("7c9e6579-7425-40de-944b-e07fc1f90az9"), ModificationDate: $qt: "2015-08-30: 10:25:00.100);
对于这种情况,我在我的收藏中创建了一个这样的索引:
db.UserBooks.createIndex(BookId: 1, UserId: 1, ModificationDate: -1)
之后,我使用 BookId 和 UserId 在 Mongo Shell 上使用 explain() 运行了一个查询,令我惊讶的是,没有使用新索引!我现在不在工作,所以我不能在这里发布可解释的结果,但我可以说它对 20.000 个键和文档进行了 COLLSCAN!
我试图在网上寻找答案,但找不到太多东西。我发现 MongoDB 不适用于 GUID 类型。这提出了几个问题:
1:MongoDB 真的不“喜欢” GUID?
2:按升序或降序排列 GUID 类型没有“意义”。因此,当我在这些类型上创建索引时,我应该始终指定 1:升序吗?有关系吗?
3:在 Mongo Shell 上查询具有 GUID 的集合时,它们显示为 BinaryData(hash)。为什么?
这个特定的应用程序有一个 SQL Server 数据库。当我们有突变数据或需要非常快速的访问时,我们会在某些情况下使用 MongoDB。这些 GUID 类型是 SQL Server 数据库中的 Id。有谁知道如何解决这个问题?或者给我指个方向?
【问题讨论】:
1.不能这么说,但 GUID 被解释为二进制数据(如二进制数组)。 2.无所谓。 3. 见 1. 对于键是 ObjectId/String 的首选用法(您可以根据 Guid 生成器为字符串制作自定义生成器)。但根据我的经验,Guid 键在索引中效果很好。您确定索引是在查询运行时创建的吗(不要选中“在后台创建”以确保这一点)。 我可以将 BookId 和 UserId 更改为字符串,但 _id 没有。假设它是一个已经投入生产的应用程序,更改 _id 的类型会导致几个问题。并且需要重构应用程序逻辑。我将把查询中的参数更改为字符串来进行这个测试,看看会发生什么。 我尝试在查询此类索引(使用 GUID)时检查我的查询格式并为您提供更多信息。正如我所说的那样,“引导式”索引效果很好。 我看到 MongoDb 的 C# 驱动程序为查询表示中的 GUID 生成,例如“new BinData(3,"-
因此 MongoDb 使用 GUID 并将它们解释为 UUID 数据格式(所谓的 BinData)。如需更多信息,请参阅:http://docs.mongodb.org/manual/reference/bson-types/ 和 http://docs.mongodb.org/manual/reference/method/UUID/
在实践中,我从未见过 GUID 索引的顺序很重要的情况,因此默认情况下您可以使用升序。
请参阅第 1 页,如文档中所述 - GUID 在 MongoDb BSON 类型系统中确实是 BinData 格式。因此,唯一的字符串或 ObjectId 是用作主键 (_id) 的引用类型。
因此,我们在 cmets 对话期间取得了成果 - 复合(多字段)索引与 C# 驱动程序查询配合得很好。
【讨论】:
以上是关于MongoDB + C#:未选择/使用 GUID 字段上的复合索引的主要内容,如果未能解决你的问题,请参考以下文章