为什么 Azure Cosmos 查询在指定分区键时具有更高的 RU?

Why do Azure Cosmos queries have higher RUs when specifying the partition key?

我有一个类似于 的问题。基本上,我一直在测试使用分区键的不同方式,并且注意到在任何时候,查询中引用的分区键越多,RU 就越高。它非常一致,甚至与分区键的使用方式无关。所以我将其缩小到测试的基本查询。

首先,这个数据库有大约 850K 个文档,所有文档的大小都超过 1KB。分区键基本上是数字形式的 id 的 100 模数,设置为 /partitionKey,容器使用默认索引策略:

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/\"_etag\"/?"
        }
    ]
}

这是我的基本查询测试:

SELECT c.id, c.partitionKey
FROM c
WHERE c.partitionKey = 99 AND c.id = '99999'
-- Yields One Document; Actual Request Charge: 2.95 RUs
SELECT c.id, c.partitionKey
FROM c
WHERE c.id = '99999'
-- Yields One Document; Actual Request Charge: 2.85 RUs

Azure Cosmos 文档说如果没有分区键,查询将“fan out”到所有逻辑分区。因此,我完全希望第一个查询以单个分区为目标,第二个查询以所有分区为目标,这意味着第一个查询应该具有较低的 RU。我想我正在使用 RU 结果作为证据来证明 Cosmos 是否正在展开并扫描每个分区,并将其与文档所说的应该发生的情况进行比较。

我知道这些结果仅相差 0.1 RU。但我的观点是查询越复杂,差异就越大。例如,这是另一个稍微复杂一点的查询:

SELECT c.id, c.partitionKey
FROM c
WHERE (c.partitionKey = 98 OR c.partitionKey = 99) AND c.id = '99999'
-- Yields One Document; Actual Request Charge: 3.05 RUs

请注意,RU 继续增长,并且完全没有指定分区键。相反,我希望上面的查询只针对两个分区,而不是没有分区键检查,它应该扇出到所有分区。

我开始怀疑分区键检查是在其他过滤器之后(或在每个分区扫描内部)进行的。例如,回到第一个查询,但将 id 更改为不存在的内容:

SELECT c.id, c.partitionKey
FROM c
WHERE c.partitionKey = 99 AND c.id = '99999x'
-- Yields Zero Documents; Actual Request Charge: 2.79 RUs
SELECT c.id, c.partitionKey
FROM c
WHERE c.id = '99999x'
-- Yields Zero Documents; Actual Request Charge: 2.79 RUs

请注意,RU 完全相同,并且两者(包括 分区筛选器)的 RU 都比文档存在时少。这似乎是对结果执行分区过滤器的症状,而不是限制扇出。但这不是文档所说的。

为什么在指定分区键时 Cosmos 具有更高的 RU?

就像评论中指定的那样,如果您是通过门户网站(或通过代码,但使用您提供的查询)进行测试,它将变得更加昂贵,因为您不是在查询特定分区,而是在查询所有内容,然后引入另一个过滤器,这是更多的费用。

您应该做的是 - 在代码中使用正确的方式来传递分区键。我的结果非常令人印象深刻:3 ru\s 有 PK 和 20.000 ru\s 没有 PK,所以我对 intworks 很有信心(我有一个非常大的数据集)