你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

查询 Azure Cosmos DB 容器

适用范围: NoSQL

本文介绍如何在 Azure Cosmos DB 中查询容器(集合、图形或表)。 具体而言,它介绍了分区中查询和跨分区查询在 Azure Cosmos DB 中如何工作。

分区中查询

从容器中查询数据时,如果查询指定了分区键筛选器,则 Azure Cosmos DB 会自动优化查询。 它会将查询路由到筛选器中指定的分区键值所对应的物理分区

例如,请考虑以下针对 DeviceId 使用等式筛选器的查询。 如果在按 DeviceId 分区的容器上运行此查询,此查询会筛选到单个物理分区。

SELECT * FROM c WHERE c.DeviceId = 'XMS-0001'

与前面的示例一样,此查询也会筛选到单个分区。 添加筛选器(按 Location)不会更改以下查询:

SELECT * FROM c WHERE c.DeviceId = 'XMS-0001' AND c.Location = 'Seattle'

下面的查询有一个针对分区键的范围筛选器,该查询的作用域不会限定于单个物理分区。 为了成为分区中查询,该查询必须具有包含分区键的等式筛选器:

SELECT * FROM c WHERE c.DeviceId > 'XMS-0001'

跨分区查询

下面的查询没有针对分区键 (DeviceId) 的筛选器。 因此,它必须根据每个分区的索引扇出到运行它的所有物理分区:

SELECT * FROM c WHERE c.Location = 'Seattle`

每个物理分区都有其自己的索引。 因此,在容器上运行跨分区查询时,可以高效地对 每个 物理分区运行一个查询。 Azure Cosmos DB 会自动聚合跨不同物理分区的结果。

不同物理分区中的索引彼此独立。 Azure Cosmos DB 中无全局索引。

并行跨分区查询

Azure Cosmos DB SDK 1.9.0 及更高版本支持并行查询执行选项。 并行跨分区查询可用于执行低延迟、跨分区查询。

可以通过调整以下参数来管理并行查询执行:

  • MaxConcurrency:设置容器分区的最大并发网络连接数。 如果将此属性设置为 -1,则由 SDK 管理并行度。 如果 MaxConcurrency 设置为 0,则与容器的分区之间存在单个网络连接。

  • MaxBufferedItemCount:权衡查询延迟与客户端内存利用率。 如果省略此选项或将其设置为 -1,则由 SDK 管理并行查询执行过程中缓冲的项目数。

由于 Azure Cosmos DB 能够并行执行跨分区查询,因此,随着系统添加 物理分区,查询延迟通常会扩展。 但是,随着物理分区总数增加,RU 费用会明显增加。

运行跨分区查询时,实质上是对每个物理分区执行单独的查询。 虽然跨分区查询将使用索引(如果可用),但它们仍然不如分区内查询高效。

有用的示例

下面是一个类比,更好地解释了跨分区查询:

假设你是送货司机,必须把包裹送往不同的公寓楼。 每栋公寓楼内都有一份列表,包含所有住户的单元号。 我们可以将每栋公寓楼与物理分区进行比较,并将每个列表与物理分区的索引进行比较。

我们可以使用以下示例来比较分区中查询和跨分区查询:

分区内查询(示例)

如果送货司机知道正确的公寓楼(物理分区),那么他们可以立即开车到正确的大楼。 司机可以查看公寓楼的住户单元号列表(索引),并迅速送达相应的包裹。 在这种情况下,司机不会浪费任何时间或精力开车前往公寓楼,查看是否有包裹收件人住在那里。

跨分区查询(扇出)

如果送货司机不知道正确的公寓楼(物理分区),需要开车前往每一栋公寓楼,并检查列表上所有住户的单元号(索引)。 在司机到达每栋公寓楼后,仍然可以使用每个住户的地址列表。 但是,他们需要检查每栋公寓楼的列表,无论是否有包裹收件人住在那里。 此示例展示了跨分区查询的工作方式。 虽然他们可以使用索引(意味着无需挨户敲门),但必须分别检查每个物理分区的索引。

跨分区查询(仅限于几个物理分区)

如果送货司机知道所有的包裹收件人都住在某几栋公寓楼,就无需开车前往每栋公寓楼。 虽然开车前往几栋公寓楼的工作量仍然比只去一栋楼要大,但送货司机仍然可以节省大量的时间和精力。 如果查询的筛选器中包含分区键和 IN 关键字,它只会检查相关物理分区的索引中的数据。

避免跨分区查询

对于大多数容器,不可避免地要进行一些跨分区查询,这没关系! 对于逻辑分区键和物理分区,几乎所有查询操作都支持跨分区。 为了跨物理分区并行执行查询,Azure Cosmos DB 在查询引擎和客户端 SDK 中也进行了许多优化。

对于大多数读取繁忙的场景,建议在查询筛选器中选择最常用的属性。 你还应该确保分区键遵循其他分区键选择最佳做法

避免跨分区查询通常只对大型容器很重要。 每次检查物理分区的索引以获取结果时,至少需要约 2.5 RU 的费用,即使物理分区中没有项与查询的筛选器匹配。 因此,如果只有一个(或几个)物理分区,跨分区查询消耗的 RU 不会明显高于分区内查询。

物理分区的数量与已预配 RU 的数量相关。 每个物理分区允许最多 10,000 个预配 RU,并且最多可以存储 50 GB 的数据。 Azure Cosmos DB 会自动为你管理物理分区。 容器中的物理分区数取决于预配的吞吐量和消耗的存储。

如果工作负载满足以下条件,应尝试避免使用跨分区查询:

  • 你计划预配 30,000 个以上的 RU
  • 你计划存储超过 100 GB 的数据

后续步骤

请参阅以下文章,了解 Azure Cosmos DB 中的分区: