【发布时间】: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,"
")”。正如我看到的那样执行使用我的索引(包含 Guid 和 Int64 字段)。但是当我使用 UUID 格式运行它时,它也可以很好地使用索引。 -
是的,MongoDb C# 驱动似乎支持它。 stackoverflow.com/questions/13254784/… 但是我使用 MongoVUE 进行查询测试
标签: c# mongodb mongodb-.net-driver database-performance