【问题标题】:Range query on secondary index in cassandracassandra中二级索引的范围查询
【发布时间】:2016-06-13 16:45:31
【问题描述】:

我正在使用 cassandra 2.1.10。 所以首先我要清楚,我知道二级索引在 cassandra 中是反模式的。但出于测试目的,我正在尝试以下操作:

CREATE TABLE test_topology1.tt (
    a text PRIMARY KEY,
    b timestamp
) WITH 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'}
    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99.0PERCENTILE';
CREATE INDEX idx_tt ON test_topology1.tt (b);

当我运行以下查询时,它给了我错误。

cqlsh:test_topology1> Select * from tt where b>='2016-04-29 18:00:00' ALLOW FILTERING;
InvalidRequest: code=2200 [Invalid query] message="No secondary indexes on the restricted columns support the provided operators: 'b >= <value>'"

虽然Blog 表示允许过滤可用于查询二级索引。 Cassandra 安装在 windows 机器上。

【问题讨论】:

  • thread 中不是您的两个答案解释了在二级索引上不可能进行范围查询。您引用的帖子还解释说,二级索引查询中的 >= 限制仅适用于非索引列并且仅当您允许过滤时才可能。
  • @Ralf 答案之一还说允许过滤将允许范围查询。还有我在问题中提到的 cassandra 的博客和这个帖子 stackoverflow.com/questions/34540883/… 建议相同

标签: cassandra cassandra-2.0 cql3


【解决方案1】:

Cassandra 2.2.x 及以下版本不允许对二级索引列进行范围查询。但是,正如帖子 A deep look at the CQL WHERE clause 指出的那样,如果允许过滤,它们可以在非索引列上使用:

对二级索引的直接查询仅支持 =、CONTAINS 或 包含关键限制。

[..]

二级索引查询允许您限制返回的结果 使用 =、>、>=、

所以,给定表结构和索引

CREATE TABLE test_secondary_index (
     a text PRIMARY KEY,
     b timestamp,
     c timestamp 
);
CREATE INDEX idx_inequality_test ON test_secondary_index (b);

以下查询失败,因为对索引列进行了不等式测试:

SELECT * FROM  test_secondary_index WHERE b >= '2016-04-29 18:00:00' ALLOW FILTERING ;
InvalidRequest: code=2200 [Invalid query] message="No secondary indexes on the restricted columns support the provided operators: 'b >= <value>'"

但以下方法有效,因为不等式测试是在非索引列上完成的:

SELECT * FROM  test_secondary_index WHERE b = '2016-04-29 18:00:00' AND c >= '2016-04-29 18:00:00' ALLOW FILTERING ;

 a | b | c
---+---+---

(0 rows)

如果您在 c 列上添加另一个索引,这仍然有效,但仍然需要 ALLOW FILTERING 术语,这对我来说意味着在这种情况下不使用列 c 上的索引。

【讨论】:

    【解决方案2】:

    范围查询DOES使用ALLOW FILTERING

    与二级索引一起工作
    cqlsh:spark_demo> create table tt (
                  ...     a text PRIMARY KEY,
                  ...     b timestamp
                  ... );
    cqlsh:spark_demo> CREATE INDEX ON tt(b);
    cqlsh:spark_demo> SELECT * FROM tt WHERE b >= '2016-03-01 12:00:00+0000';
    InvalidRequest: code=2200 [Invalid query] message="No supported secondary index found for the non primary key columns restrictions"
    cqlsh:spark_demo> SELECT * FROM tt WHERE b >= '2016-03-01 12:00:00+0000' ALLOW FILTERING;
    
     a | b
    ---+---
    
    (0 rows)
    cqlsh:spark_demo>
    

    【讨论】:

    • 能否请您确认cassandra版本、cql版本和操作系统。因为它不适用于 windows cassandra 2.1.10
    • Cassandra 3.3,操作系统 = Mac OS X 10.11.1 El Capitan
    • 我必须检查 3.0 或更高版本,因为这在 2.1 中不起作用。
    • @doanduyhai 这在内部是如何工作的?二级索引的数据结构是什么?是B树吗?还是带有主键“b”的隐藏表?我假设在每个节点中都创建了二级索引。如果是这样,这个查询在所有节点上执行某种分散收集操作?
    【解决方案3】:

    这将为您带来您想要的结果。使用 b 作为聚类列。

    创建表 test_topology1.tt ( 一段文字, b 时间戳, 主键 (a, b) )

    select * from tt where b>='2016-04-29 18:00:00' 允许过滤;

    【讨论】:

    • 我知道会的。我正在寻找的是为什么范围查询不适用于二级索引,当博客这么说时允许过滤
    猜你喜欢
    • 2023-04-08
    • 2017-11-25
    • 1970-01-01
    • 2015-11-09
    • 2016-11-28
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    相关资源
    最近更新 更多