Azure cosmosdb DocumentDB索引性能/碎片

Azure cosmosdb DocumentDB索引性能/碎片,azure-cosmosdb,Azure Cosmosdb,我已决定为我的文档实施以下ID策略,该策略将文档“类型”与ID相结合: doc.id = "docType_" + Guid.NewGuid().ToString("n"); // create document in collection 这将为我的文档生成如下ID: usr\u 19d17037ea7f41a9b20db1a90f71d30d usr\u 89fe82c93b264076aa1b6e1fb4813aaf usr2aa58c970a4c5eaa206a755c7bf4 ms

我已决定为我的文档实施以下ID策略,该策略将文档“类型”与ID相结合:

doc.id = "docType_" + Guid.NewGuid().ToString("n");

// create document in collection
这将为我的文档生成如下ID:

usr\u 19d17037ea7f41a9b20db1a90f71d30d

usr\u 89fe82c93b264076aa1b6e1fb4813aaf

usr2aa58c970a4c5eaa206a755c7bf4

msg_ec43510732ae47a6a5d5f323b7461d68

msg_3b03ceeb7e06490d998c3e368b435851

有了ID上的
RangeIndex
策略,我应该能够查询集合中的特定类型。例如:

SELECT * FROM c WHERE STARTSWITH(c.id, 'usr_') AND ...
由于这是一个具有许多不同文档类型的web应用程序,因此默认情况下,我的应用程序的许多查询都会实现此
STARTSWITH
过滤器

我主要关心的是在ID上使用随机GUID字符串。我知道在SQL Server中,在聚集索引的主键上使用随机GUID时,我遇到了索引性能和碎片问题


这里有类似的担忧吗?在DocumentDB中,管理索引的工作似乎已经从您这里抽象出来了。顺序ID在任何方面是否更理想/性能更好;dr:对类型和仅GUID ID使用单独的字段,并对两者使用哈希索引

根据你问题的性质,这个答案必然会有点固执己见。首先,让我谈谈您最关心的问题,即影响性能的索引碎片

DocumentDB假定使用GUID和哈希索引(与范围索引相反)非常适合按GUID查找一个匹配的实体。另一方面,如果您想通过查看字符串的开头来查找一组文档,我认为使用范围索引可能会更有效。这假设StartWith仅在与范围索引一起使用时才进行优化,但我不知道它是否在有范围索引的情况下进行了优化

我的建议是对类型和仅GUID的ID使用单独的字段,并对两者使用哈希索引。这样做的好处是可以确保像您显示的那样的查询将具有很高的性能,并且将type子句与其他参数组合在一起的查询也可以使用至少一个索引。注意,这种类型的散列索引(比如2x 3字节=6字节/文档)具有很高的空间效率,所以不必担心需要两个。这两个索引的组合应该比一个范围索引小得多,范围索引需要有足够的精度来覆盖类型+GUID的整个长度

除了已经讨论过的性能和空间方面的原因外,我可以看到将类型与GUID相结合还有一些其他缺点:1)在尝试检索单个文档时(无论是直接使用还是作为外键查找的一部分),将GUID分开并使用哈希索引将比在组合字段上使用范围索引更快、更节省空间;2) 将类型与ID相结合会使某些迁移变得非常复杂,这些迁移通常需要在以后完成。例如,假设您决定将用户分为作者和读者。用户是用户ID在其他文档类型(博客文章作者、读者评论等)中引用的外键。如果该ID包含该类型,则您不仅需要更改用户文档以完成迁移,还需要查找和更改每个外键。如果这两个字段(GUID和类型)是分开的,那么您只需要更改用户文档。敏捷软件工艺在很大程度上是关于做出能够提供灵活性的决策


至于顺序索引的使用,一般数据库和NoSQL中的趋势是,提供单调递增的顺序ID的复杂性大于提供GUID的空间效率优势。如果您打算坚持使用DocumentDB,我建议您只需遵循流程并使用GUI。

谢谢您的精彩回答!我试图想出一种方法,不必在我的应用程序POCO中添加额外的类型字段,但我想这只是必要的。现在这有点道理了。我想这只是我的SQL和NoSQL知识有点混淆,导致我试图发明一些新的东西。