【问题标题】:What is the costs of querying on subdocuments in cosmosdb?在 cosmosdb 中查询子文档的成本是多少?
【发布时间】:2018-07-21 04:41:15
【问题描述】:

在 cosmosdb 中查询子文档的成本是多少?在阅读文档时,似乎只有 ID 及其路径被索引。

这是否意味着每次querying on a subdocuments 使用From 子句如下:

SELECT * 
FROM Families.children

它将解析匹配此路径的文档并创建它们的视图?是否也存储子文档?

【问题讨论】:

  • 不确定您在哪里看到的,但是... 所有属性都已编入索引,包括子文档属性。搜索子文档的查询不会进行解析。至于成本,您可以通过查看标头中返回的请求单位费用来衡量查询。如果您通过门户运行查询,它也会显示给您。
  • 所有属性都被索引是什么意思?完整的 json 路径(ex /locations/0/country/france)将根据以下文档和论文关联到文档的 id:docs.microsoft.com/en-us/azure/cosmos-db/indexing-policiesvldb.org/pvldb/vol8/p1668-shukla.pdf。但是当我们使用 FROM 过滤时,它是否也直接存储子文档的内容以在查询期间使用它们?我很好奇对它们进行查询的效率如何。
  • 换句话说是在索引期间存储的子文档还是只是它们的路径?

标签: azure azure-cosmosdb azure-cosmosdb-sqlapi


【解决方案1】:

索引的工作原理

CosmosDB 将整个 JSON 文档存储为一棵树(任何深度,包括我猜你所说的“子文档”)。 FROM..IN 连接语法只是一种语法糖,可以让您更轻松地在 SQL 查询中表达这些路径。例如,从树路径中“删除”数组索引并为SELECTWHERE 部分提供漂亮的快捷方式。它实际上从未在您的查询中包含更多数据,只是将命名指针分配给每个要返回的根文档中的部分。

索引路径仅包含对匹配文档根的引用,它们不会复制“子文档”。与关系 SQL 不同,CosmosDB 中没有覆盖索引。

当您“选择一个子文档”时,您实际上是在指示 cosmosDB 将一个投影从根文档树表示返回到它的子部分。从某种意义上说,它是对原始文档的(非序列化)视图。

一定要去看看视频Azure Cosmos DB Indexing,它解释得很好。主要内容是这张图片(上面视频的截图):

关于性能

对性能最重要的不是你如何引用索引树中的节点,而是它是否被索引并且是否足够有选择性。索引值驻留在文档中的位置实际上并不太相关。

我猜想更深入地遍历索引树(和文档树)存在理论上的开销,但我很确定这种影响在实践中是如此微小,你通常甚至无法测量它。 N ms 查询中的大部分工作都花在了其他地方(从索引检查匹配文档的附加谓词,从内部树模型构建输出 Json 对象,序列化)。

与关系 SQL 类似,与完整的根文档相比,仅返回“子文档”很可能稍微快一些,因为 SELECT 步骤可以跳过文档树的不相关部分。但可能它更多地取决于整体包含的树节点数和数据大小,而不是树的形状。

.. 以及关于性能的通常建议 - 请编写一些测试。对于 CosmosDB,您可以测量 RU 成本并检查 PopulateQueryMetrics header

更新:是否存储子文档?

上面的图形表明它们不是 - 仅链接到根文档。但这显然是一种简化,因此不是结论性的。不过,您应该能够为此设计一个测试。另一种方法是通过 askcosmosdb@microsoft.com 向团队询问内部设计。

【讨论】:

  • 谢谢。但是我链接的论文提供了相同的信息。但这是我遗漏的最后一步:表单如何在给定的路径上获取提取的值。它是作为片段存储在某处(论文建议有一些片段ID)还是总是遍历与索引对应的文档以返回值?
  • 啊,我看错了你的问题焦点。在这里没有真正回答您的问题,尽管它可能对其他一些读者有用的信息+测试它的建议仍然有效。如果您想了解内部设计和实现的细节,您应该直接询问 cosmosDB 团队。
猜你喜欢
  • 1970-01-01
  • 2020-09-24
  • 1970-01-01
  • 2019-09-25
  • 2020-12-03
  • 2020-07-16
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
相关资源
最近更新 更多