database - 选择带有允许过滤的低基数列会抛出错误 : No secondary indexes on the restricted columns support the provided operators

标签 database indexing cassandra cql nosql

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 子句的一部分)都需要作为主键的一部分或单独的索引进行索引。

对于复合键,需要包含键的最左边部分,以便能够在键的最右边部分进行搜索。

例如,如果复合键是 (type, scope, name, deleted) 并且想要查询 deleted 则需要提供 type, scope,名称。要查询名称,至少需要提供类型、范围等。

deleted 作为键的倒数第二部分使其可以搜索,而不会产生额外的开销,因为额外的索引会产生,并且与 deleted 的基数很低一样有效(或不有效)。

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);

请注意删除双 和 type='type',包含删除的所有可能值以便能够在版本上搜索并删除允许过滤(性能不佳)。

一般来说,制作一个适合您的查询的模式。首先考虑“我将如何查询”以帮助您决定将什么作为主键以及以什么顺序放置。忘记关系数据库语义,它们不适用。

关于database - 选择带有允许过滤的低基数列会抛出错误 : No secondary indexes on the restricted columns support the provided operators,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39222463/

相关文章:

mysql - 如何优化我的数据库?

java - 将多个 Lucene 索引与相同结构的文档结合起来,用于查询和排序

python:我可以在不(明确)使用整数索引的情况下获得稀疏矩阵表示吗?

c# - 为任意参数可以为空的两个表选择记录

mysql - 数据库设计——将每个公司与所有可能的邮政编码连接起来以存储距离

database - 具有未知外键的 SQLite 关系 INSERT

Python igraph 顶点索引

cassandra - 观察者可以在哪里写入 Cassandra 数据库,也就是它们在哪里记录?

mysql - 数据未使用 Sqoop 从 MySql 导入到 Cassandra

apache-spark - 如何在 Spark 和 Cassandra 之间配置 SSL?