Compound Couchbase 4.x 全球二级索引

Compound Couchbase 4.x Global Secondary Indexes

在 Couchbase 4.x 中创建 compound 全局二级索引时,我很好奇基于 CREATE INDEX 语句期间提供的字段排序的性能。

为了说明,让我从一个例子开始:

CREATE INDEX Index_1 
 ON `bucket`(field1, field2) 
 USING GSI;

现在当我们执行以下查询时:

SELECT * FROM `bucket`
 WHERE `bucket`.field1 = "value1"
 AND `bucket`.field2 = "value2";

我很清楚使用 Index1 是显而易见的。但是,有一些情况我不清楚:

  1. 如果只提供了字段 2 而没有提供字段 1 怎么办?

    SELECT * FROM bucket WHERE bucket.field2 = "value2";

  2. 如果WHERE子句中field2和field1的顺序相反怎么办?

    SELECT * FROM bucket WHERE bucket.field2 = "value2" AND bucket.field1 = "value1";

我知道这个例子只适用于 2 个字段,但在我的例子中,我有大约 10 个字段。在这种情况下,创建许多索引来涵盖所有可能性似乎是组合爆炸(甚至阶乘,如果您考虑所有可能的排序并且排序很重要)。如果缺少的字段很重要,那就更糟了,因为那样您将需要对可能的字段子集进行所有可能的排序。即[(field1, field2), (field1), (field2, field1), (field2)],这只针对2个字段。

CREATE INDEX 语句中的字段顺序确实很重要。您的查询必须包含前导字段 field1,但可以选择包含尾随字段。您的索引只有一个尾随字段 field2

您的第一个查询将不会使用该索引,因为它缺少前导字段。确保在测试索引时删除主索引或检查计划以确保它不包含 PrimaryScan

如第二个示例所示,重新排序查询谓词不会改变索引的使用方式。 IndexScan 中使用所有前导字段,无论它们出现在查询谓词中的什么位置。

但是,如果您有一个包含两个以上字段的索引,例如:

CREATE INDEX Index_2 
  ON `bucket`(field1, field2, field3, field4) 
  USING GSI;

并且您的查询排除了第二个字段:

SELECT * FROM `bucket`
  WHERE `bucket`.field1 = "value1" 
    // field2 not specified
    AND `bucket`.field3 = "value3";

仅指定了一个前导字段,因此仅使用 field1 谓词扫描索引。查询服务必须完成剩余工作以过滤具有 field3 值的项目。