问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Azure Cosmos DB SQL API 索引使用指南

创作时间:
作者:
@小白创作中心

Azure Cosmos DB SQL API 索引使用指南

引用
1
来源
1.
https://learn.microsoft.com/zh-cn/training/modules/choose-indexes-azure-cosmos-db-sql-api/2-index-usage?ns-enrollment-id=learn.wwl.optimize-query-performance-azure-cosmos-db-sql-api&ns-enrollment-type=learningpath&source=recommendations

索引使用情况

查询引擎会计算查询筛选器,然后遍历容器的索引。 查询引擎会自动尝试使用以下三种计算筛选器的方法中最高效的方法:

方法
说明
RU 影响
索引查找
查询引擎会直接遍历到某个字段的值并查找匹配的项数,从而搜索该字段值的精确匹配。 确定匹配的项后,查询引擎会返回这些项作为查询结果。
查找的 RU 费用是不变的。 加载和返回项的 RU 费用基于项数线性变化。
索引扫描
查询引擎会查找字段的所有可能值,然后仅对值执行各种比较。 找到匹配项后,查询引擎会加载并返回这些项作为查询结果。
查找的 RU 费用仍是不变的,不过基于索引属性的基数,会略高于索引搜索。 加载和返回项的 RU 费用仍基于返回的项数线性变化。
完全扫描
查询引擎会将整个项加载到事务存储,以计算筛选器。
此类型的扫描不使用索引;但是,加载项的 RU 费用基于整个容器中的项数。

注意:索引扫描的复杂性可以从高效精确的索引扫描到更复杂的扩展索引扫描,最后是最复杂的完整索引扫描。

作为查询开发人员,必须了解哪些查询需要搜索与扫描。 了解哪些查询不能使用索引,而是需要完全扫描也十分重要。 具体而言,应优化查询以便使用的筛选器谓词使用最高效的查找方法。

我们来演示属性和查询如何影响查找方法。 在此示例中,一个虚构容器具有三个带有唯一标识符的项、一个 name 字符串属性和一个 price 数值属性。

[
  {
    "id": "1",
    "name": "Touring-1000 Blue",
    "price": 675.55
  },
  {
    "id": "2",
    "name": "Mountain-400-W Silver",
    "price": 1215.40
  },
  {
    "id": "3",
    "name": "Road-200 Red",
    "price": 405.85
  }
]

每个项都可以可视化为树。

对于第一个项,树表示形式包括一个 name 节点(带有 Touring-1000 Blue)和一个 price 节点(带有 675.55 子值节点)。

第二个项的树会具有相同的节点,其值分别为 Mountain-400-W Silver 和 1215.40。

最后一个项的树是类似的,值为 Road-200 Red 和 405.85。

包含所有三个项的倒置树会具有一个匹配所有三个项的根节点。 从概念上来说,可以将遍历根节点视为与没有筛选器的查询类似。 该树包含一个 price 节点,有三个子节点对应于每个不同值。 price 节点匹配所有三个项,因为每个项都包括 price 字段。 但是,每个单独的 price 节点仅与单个项匹配,因为每个项的价格是不同的。 该树还包含一个 name 节点,该节点匹配所有三个项,各个子节点对应于每个不同值。

为了遍历树,编写一个简单 SQL 查询,其筛选器仅匹配 name 等于 Touring-1000 Blue 值的项。

SELECT 
    *
FROM
    products p
WHERE
    p.name = 'Touring-1000 Blue'

查询引擎随后可以按以下顺序遍历树:

  1. 引擎会在根处开始。 目前,所有项仍是潜在的匹配项。
  2. 引擎会遍历 name 节点。 所有项仍然匹配。
  3. 最后,引擎会遍历精确匹配的 Touring-1000 Blue 节点。 此时只有项 #2 匹配
  4. 查询引擎随后会加载项 #2 的整个 JSON 内容,并在结果集中返回该内容。

此树图演示了向下遍历到 Touring-1000 Blue 节点的过程。

此遍历是是实际运行的索引搜索查找方法的示例。 精确值的实际匹配是固定费用(以 RU/s 为单位),因为查询引擎会使用索引而不是在每个项的 JSON 内容中搜索。 找到匹配的项后,查询引擎会加载 JSON 内容以返回到客户端应用程序。

如果查询筛选器不匹配任何已知值,则结果集不会返回任何项。 如果多个项对于字段具有相同值,则树会指示查询引擎返回多个项。

索引搜索的另一个示例是使用 IN 筛选器对多个可能字段执行相等匹配的 SQL 查询。

SELECT 
    *
FROM
    products p
WHERE
    p.name IN ('Road-200 Red', 'Mountain-400-W Silver')

查询引擎随后会按以下顺序遍历树:

  1. 引擎会在根处开始。 目前,所有项仍是潜在的匹配项。
  2. 引擎会遍历 name 节点。 所有项仍然匹配。
  3. 最后,引擎会遍历精确匹配项。 这包括 Road-200Red 和 Mountain-400-W Silver 节点。 此时只有项 #1 和 #3 匹配
  4. 查询引擎随后会加载项 #1 和 #3 的整个 JSON 内容,然后在结果集中返回该内容。

此树图演示了针对 name 节点中的匹配子值的遍历过程。

某些查询使用其他运算符,而这些运算符要求使用更复杂的索引查找方法。 在此示例 SQL 查询中,基于两个范围比较来筛选项。 简单说来,查询会查找价格介于 $500 和 $1,000 之间的商品。

SELECT
    *
FROM
    products p
WHERE
    p.price >= 500 AND
    p.price <= 1000

查询引擎会按以下顺序遍历树:

  1. 引擎会在根处开始。 目前,所有项仍是潜在的匹配项。
  2. 引擎会遍历 price 节点。 所有项仍然匹配。
  3. 查询引擎会对所有可能值执行二进制文件搜索,以指示它们是否与筛选器匹配。
  4. 最后,引擎会将匹配项值映射到其项。 只有 675.55 节点匹配。 那么,此时只有项 #1 匹配。
  5. 查询引擎随后会加载项 #1 的整个 JSON 内容,然后在结果集中返回该内容。

在复杂性方面,此二进制文件搜索将查询从索引搜索转为精确索引扫描。 查询引擎会扫描索引中的所有可能值,但这比完整扫描所有 JSON 内容仍然要高效得多。 使用范围比较和字符串函数的查询通常会要求使用索引扫描。

在某些极端情况下,查询引擎无法使用索引来计算筛选器。 在计算筛选器之前,这些情况要求查询引擎将所有项的 JSON 内容加载到事务性存储区中。 完整扫描可能会产生大量的请求单位费用,因为费用会随着容器中的总项数一起线性缩放。 尽管完整扫描很少进行,但必须知道,在查询筛选器中使用特定内置函数时可以进行这种扫描。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号