检查 Azure CosmosDB 中定义的索引

问题描述 投票:0回答:1

我目前正在扩展现有系统,需要对包含约 300 万个文档的容器“Parts”进行新查询。我使用以下查询来查找所有文档,其中包含“parts”数组中的项目,partNumber为“ABC12345”:

// 69 RUs small test
SELECT c.partNumber 
FROM c
WHERE ARRAY_CONTAINS(c.parts, { 'partNumber': 'ABC12345'}, true)

这个查询非常慢。对于某些参数,这将需要几秒钟,占用约 100 RU,但对于更频繁发生的匹配,这将花费更长的时间,并占用数千 RU。这是个问题。此测试是使用 Azure 门户完成的(如果有影响的话)。

我首先尝试优化查询,但这并没有提高性能。我一直在研究这个问题,与我对 CosmosDB 的最初理解相反,数组默认情况下没有索引。因此,我在属性partNumber中添加了一个索引,希望能够优化性能,如下:

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

但是,我没有看到性能有任何改进。如何验证索引是否正确定义;有没有办法“浏览”CosmosDB 索引,以便我可以确保我已正确设置并正确使用索引?

在开始寻求替代解决方案之前,我想首先验证这一点。

azure-cosmosdb
1个回答
0
投票

零件数组上的值字段partNumber应该已经被索引,因为所有字段都被索引,除非您特别排除它们。

我认为您的实际问题是使用 ARRAY_CONTAINS 并将 true 作为最后一个参数传递(partial_match)。根据我的经验,无论索引如何,这往往会导致完整的集合扫描。当部分匹配为 true 时,它在逻辑上相当于 string CONTAINS 等函数,但与索引不能很好地配合。

我相信您可以使用联接和相等子句来表达查询,而不是 ARRAY_CONTAINS,这应该命中索引。

SELECT
  c.partNumber
FROM
  c
JOIN
  p IN c.parts
WHERE
  p.partNumber = 'ABC12345'
© www.soinside.com 2019 - 2024. All rights reserved.