在Couchbase 4.x中创建复合全局二级索引时,我对基于CREATE INDEX语句中提供的字段顺序的性能感到好奇。
为了说明,让我先举一个例子:
CREATE INDEX Index_1
ON `bucket`(field1, field2)
USING GSI;
现在我们执行以下查询:
SELECT * FROM `bucket`
WHERE `bucket`.field1 = "value1"
AND `bucket`.field2 = "value2";
我很清楚使用Index1是显而易见的。但是,有一些我不清楚的案例:
SELECT * FROM
bucket
WHEREbucket
。field2 =“value2”;
SELECT * FROM
bucket
WHEREbucket
。field2 =“value2”ANDbucket
。field1 =“value1”;
我知道这个例子只适用于2个字段,但在我的情况下,我有10个字段。在这种情况下,创建许多索引以涵盖所有可能性似乎是一个组合爆炸(甚至,如果你考虑所有可能的排序和排序是重要的因素)。如果缺少字段很重要,那就更糟了,因为那时你需要对可能的字段子集进行所有可能的排序。也就是说,[(field1,field2),(field1),(field2,field1),(field2)],这仅适用于2个字段。
答案 0 :(得分:1)
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
值的项目。