You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过JOIN过滤嵌套列表时Cosmos索引是否生效?如何验证?

Cosmos DB索引使用验证及相关疑问

数据结构

我的NoSQL Cosmos DB容器中数据结构如下:

[
    {
        "id": "SmithFamily",
        "memberCount": 3,
        "children": [{
            "name": "Foo",
            "pets": [{ "name": "Bar" }]
        }]
    },
    {
        "id": "DoeFamily",
        "memberCount": 2,
        "children": [{
            "name": "Baz",
            "pets": [{ "name": "Qux" }]
        }]
    }
]

当前索引策略

容器的索引策略配置为:

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/children/[]/pets/[]/name/?"
        },
        {
            "path": "/children/[]/name/?"
        }
    ],
    "excludedPaths": [
        {
            "path": "/*"
        }
    ]
}

查询与索引疑问

  1. 我可以通过以下查询找到宠物名为"Qux"的家庭:
SELECT f
FROM family f
JOIN child IN f.children
WHERE ARRAY_CONTAINS(child.pets, {name: "Qux"})

但不确定该查询是否会使用指定的/children/[]/pets/[]/name/?索引——官方文档未提及JOIN场景下的嵌套数组索引使用,但该索引策略配置无报错。

  1. 这对复合索引的使用尤为关键,比如我创建了如下复合索引:
"compositeIndexes": [  
    [  
        {  
            "path": "/children/[]/pets/[]/name/?",
            "order":"ascending"
        },
        {  
            "path":"/memberCount",
            "order":"ascending"
        }
    ]
]

为了让该复合索引生效,我执行了先按宠物名过滤、再按memberCount排序的查询:

SELECT f
FROM family f
JOIN child IN f.children
WHERE ARRAY_CONTAINS(child.pets, {name: "Qux"})
ORDER BY f.memberCount

如果查询未用到复合索引的第一个路径,整个复合索引就不会生效,会导致性能下降、RU消耗增加。

  1. 对于/children/[]/name/?索引,我认为执行以下查询时会生效:
SELECT * FROM c WHERE ARRAY_CONTAINS(c.children, {name: "Baz"}, true)

核心问题

请问是否有办法验证特定查询是否使用了指定索引?


验证方法及相关结论

验证查询是否使用指定索引的方式

  • 查看门户查询统计信息:在Azure门户的Cosmos DB数据资源管理器中执行查询后,点击「查询统计信息」,可以看到索引使用详情,包括是否使用了范围索引、复合索引,以及扫描的文档数量。如果查询命中目标索引,会在索引类型中对应显示,路径也会匹配你定义的索引路径。
  • 通过SDK获取QueryMetrics:使用.NET等SDK执行查询时,可获取QueryMetrics对象,里面包含IndexHitRatio(索引命中率)、IndexLookupTime等指标。若索引命中率接近100%,且计划显示使用了对应路径的索引,说明索引生效。
  • 对比RU消耗:索引生效时,查询的RU消耗会远低于全表扫描。可以临时修改索引策略为全排除(模拟无索引场景),对比两次查询的RU值,差异明显则说明索引在起作用。

关于你的查询索引使用情况

  • 带JOIN的宠物名过滤查询会使用/children/[]/pets/[]/name/?索引,因为ARRAY_CONTAINS针对嵌套数组的属性过滤时,Cosmos DB会匹配对应的数组索引路径。
  • 带排序的复合索引查询会生效,只要复合索引的路径顺序(先宠物名、再memberCount)与查询的过滤+排序逻辑匹配,Cosmos DB会优先使用复合索引完成操作,避免额外排序开销。
  • 你提到的子节点名称过滤查询确实会使用/children/[]/name/?索引,第三个参数true会触发对象属性的精确匹配,从而命中索引。

内容的提问来源于stack exchange,提问作者Christian Eriksson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 01:17:40