database – select with low-cardinality column with allow filtering抛出错误:受限列上的辅助索引不支持提供的运算符

CREATE TABLE test (
    type text,
    scope text,
    name text,
    version text,
    alias text,
    deleted boolean,
    PRIMARY KEY ((type, scope, name), version)
) WITH read_repair_chance = 0.0
   AND dclocal_read_repair_chance = 0.1
   AND gc_grace_seconds = 864000
   AND bloom_filter_fp_chance = 0.01
   AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' }
   AND comment = ''
   AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'min_threshold' : 4, 'max_threshold' : 32 }
   AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' }
   AND default_time_to_live = 0
   AND speculative_retry = '99.0PERCENTILE'
   AND min_index_interval = 128
   AND max_index_interval = 2048;
CREATE INDEX test_alias ON test (alias);
CREATE INDEX test_type_index ON test (type);

此选择不起作用:

select * 
from test 
where type = 'type' 
    and scope='scope' 
    and name='name'
    and deleted = false 
allow filtering;

并告诉我:

No secondary indexes on the restricted columns support the provided
operators: com.datastax.driver.core.exceptions.InvalidQueryException:
No secondary indexes on the restricted columns support the provided
operators.

这个选择有效:

select * 
from test 
where type = 'type' 
    and scope='scope' 
    and deleted = false 
allow filtering;

这个选择也有效:

select * 
from test 
where type = 'type' 
    and scope='scope' 
    and name='name' 
allow filtering;

这个选择也有效:

select * 
from test 
where type = 'type' 
    and scope='scope' 
    and name='name'
    and version='version' 
allow filtering;

任何的想法?我不想在低基数列上创建索引,我不明白为什么在某些情况下查询有效(当我从主键和另外的字段中删除2个字段时:删除).

Cassandra版本:2.1.14

如果我理解正确,则不可能在复合分区键和另一个字段内的所有键一起使用查询条件.但我没有找到任何解释……

最佳答案 无论需要查询什么(WHERE子句的一部分)都需要作为主键的一部分或单独的索引编制索引.

对于复合键,需要包含键的最左侧部分,以便能够搜索键的最右侧部分.

例如,如果复合键是(类型,范围,名称,已删除)并且想要在已删除时查询,则需要提供类型,范围,名称.要查询名称需要至少提供类型,范围等.

将删除作为密钥的最后一部分的第二部分使得它可以搜索而没有额外的开销会产生额外的索引,并且与删除的基数低一样有效(或不).

CREATE TABLE test (
     type text,
     scope text,
     name text,
     version text,
     alias text,
     deleted boolean,
     PRIMARY KEY (type, scope, name, deleted, version)
 );
select *  from test
  where type = 'type'
      and scope='scope'
      and name='name'
      and deleted = false;

select *  from test
  where type = 'type'
  and scope='scope'
  and name='name'
  and version='version'
  and deleted in (true,false);

请注意删除double和type =’type’,包含所有可能值的已删除,以便能够搜索版本并删除允许过滤(执行效果不佳).

通常,制作适合您查询的架构.首先想一想’我将如何查询’,以帮助您决定放置什么作为主键以及按什么顺序排列.忘记关系数据库语义,它们不适用.

点赞