Cosmos db ARRAY_LENGTH性能

时间:2018-07-06 08:34:03

标签: azure-cosmosdb

我遇到一个问题,即有效查询在应有的情况下未返回任何内容:

SELECT * 
FROM root 
WHERE 
    (ARRAY_LENGTH(root["orderData"]["_attachments"]) > 0
    AND root["orderData"]["_status"] = "ARCHIVEDVALIDATED") 
OR root["orderData"]["_status"] = "ARCHIVEDREJECTED"

感谢stackoverflow社区,我发现这是因为它占用了过多的RU,并且什么也不会返回。

在研究并尝试了服务器方面的东西之后,我发现如果删除ARRAY_LENGTH(root["orderData"]["_attachments"]) > 0,我的查询范围将从13k RU变为600 RU。

我似乎找不到解决此问题的方法,到目前为止,我发现的修补程序是从查询中删除ARRAY_LENGTH(root["orderData"]["_attachments"]) > 0并在以后的内存中对其进行过滤(这不好...)

我想念什么吗?我该如何解决?

谢谢!

2 个答案:

答案 0 :(得分:1)

要弄清楚两个查询之间的RU差异,您可能需要按照https://docs.microsoft.com/en-us/azure/cosmos-db/sql-api-sql-query-metrics检查两个查询的查询指标。

您也可以尝试交换前两个表达式,看看是否有任何区别。基本上尝试以下查询:

SELECT * FROM root WHERE (((root["orderData"]["_status"] = "ARCHIVEDVALIDATED") AND (ARRAY_LENGTH(root["orderData"]["_attachments"]) > 0)) OR (root["orderData"]["_status"] = "ARCHIVEDREJECTED"))

答案 1 :(得分:1)

600RU仍然非常非常差。那不是解决方案。

如此糟糕的性能的原因是您的查询无法使用索引,并且进行全面扫描无法扩展。现在不好了,随着收藏的增长,情况会变得更糟。

您需要确保查询可以使用索引仅检查可能的最小文档数。在不知道您在orderdata.statusorderdata._attachments.length上的价值数据分布的情况下,很难提出确切的解决方案,但是您应该考虑:

  • 删除OR 。查询“ this or that”不能使用索引。 CosmosDB每个查询仅使用1个索引。如果orderdata.status值足够有选择性,您将获得 通过执行2次调用并将结果合并到客户端中,可以大大提高RU /性能。
  • 将您的条件预先计算为单独的属性,并在其上添加索引。是的,那是在复制数据,但是几个额外的字节不会让您付出任何代价,而RU和性能会花费很多金钱和用户体验。

您也可以将它们组合起来,例如,通过2个查询并仅存储数组计数。考虑一下您的数据并进行测试。