【问题标题】:Why does including partition key in WHERE clause to Cosmos SQL API query increase consumed RUs for some queries?为什么在 Cosmos SQL API 查询的 WHERE 子句中包含分区键会增加某些查询的消耗 RU?
【发布时间】:2020-10-03 12:50:32
【问题描述】:

我想针对消耗的 RU 优化我的 Azure Cosmos DB SQL API 查询(部分是为了减少 429 响应的频率)。

具体来说,我认为在 WHERE 子句中包含分区键会减少消耗的 RU(例如,我阅读了 https://docs.microsoft.com/en-us/azure/cosmos-db/optimize-cost-querieshttps://docs.microsoft.com/en-us/azure/cosmos-db/partitioning-overview 这让我想到了这一点)。

但是,当我跑步时

SELECT TOP 1 * 
FROM c
WHERE c.Field = "some value"
AND c.PartitionKeyField = "1234"
ORDER BY c.TimeStampField DESC

它消耗 6 个 RU。

而没有分区键,例如

SELECT TOP 1 * 
FROM c
WHERE c.Field = "some value"
ORDER BY c.TimeStampField DESC

它消耗 5.76 个 RU - 即更便宜。

(虽然上述数字会根据所选的确切文档有所不同,但第二个查询总是更便宜,而且我已经针对最小和最大分区进行了测试。)

我的数据库目前有大约 400,000 个文档和 29 个分区(预计两者都会增长)。最大的分区有大约 150,000 个文档(不太可能进一步增长)。

以上结果告诉我,我不应该在 WHERE 子句中为此查询传递分区键。请问有人能解释一下为什么会这样吗?从我认为相反的文档来看应该是正确的?

【问题讨论】:

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


    【解决方案1】:

    可能有几个原因,这取决于查询引擎决定使用哪个索引或是否有索引。

    我要说的第一件事是,这个容器中可能没有太多数据,因为没有分区键的查询会随着容器越大而变得越来越昂贵,尤其是当它们跨越物理分区时。

    如果分区键上没有索引并在通过 c.field 过滤后对其进行扫描,则第一个可能会更昂贵。

    根据是否有复合索引以及是否使用它,它也可能更昂贵。

    确实,尽管您无法获取小型容器的查询指标并进行推断。衡量的唯一方法是将足够的数据放入容器中。此外,这里的数量非常小,不值得优化。我会将您希望在生产中拥有的数据量放入此容器中,然后重新运行您的查询。

    最后,关于衡量和优化,帕累托原则适用。你会发疯地追逐每一个优化。找到您的高并发查询并专注于这些查询。

    希望这有帮助。

    【讨论】:

    • 是的 - 这是从许多进程同时运行的查询,因此值得优化。我将在 WHERE 子句中保留分区键,并随着集合的增长监视查询中的 RU。
    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 2015-10-30
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    相关资源
    最近更新 更多