【问题标题】:Cassandra order by and filter through secondary indexesCassandra 通过二级索引排序和过滤
【发布时间】:2015-09-28 10:59:57
【问题描述】:

我的cassandra表结构如下:

CREATE TABLE sujata
          ... (ID int, roll_number int, age int, PRIMARY KEY (ID,roll_number));

我插入了一些记录,其中 ID 用作多行的分区。我正在执行以下查询:

SELECT count(*) FROM sujata WHERE ID=1 ORDER BY roll_number ASC and age=24 Allow Filtering;

我收到以下错误:

missing EOF at 'and' (...1 ORDER BY roll_number ASC [and] age...)">

我不知道是否可以在执行 order by 后过滤掉结果。请建议我在哪里失踪。谢谢。

【问题讨论】:

  • 试试这个:SELECT count(*) FROM sujata WHERE ID=1 and age=24 ORDER BY roll_number ASC 允许过滤
  • 上述查询不起作用,因为二级索引不支持 order by。

标签: cassandra cql


【解决方案1】:
  1. 不要使用允许过滤。它不执行或 规模,因为它允许您以它的方式查询 Cassandra 并非旨在支持。

  2. 当您尝试 ORDER BY 两件事时,CQL 将您的语句解释为 ORDER BY roll_number ASC and age=24。 AND 属于您的 WHERE 子句,需要指定 之前订购。

  3. Cassandra 使用您的集群键来写入您的数据 磁盘排序顺序。 ORDER BY 只允许您翻转排序 聚类顺序的方向(升序与降序)。所以 如果您已经在表格中指定了正确的排序顺序 定义,则无需指定 ORDER BY。

  4. 要同时通过IDage 查询您的表,您需要 将这两列作为前两列设计您的 PRIMARY KEY。 您只能查询 PRIMARY KEY 中定义的列(辅助 索引无法承受),然后仅以相同的顺序(您 不能跳过键)。为此,我创建了一个查询表 (sujataByIDAndAge) 看起来像这样:

.

CREATE TABLE sujataByIDAndAge (
    ID int, 
    roll_number int, 
    age int, 
PRIMARY KEY (ID,age,roll_number));

现在插入几行后:

aploetz@cqlsh:stackoverflow> INSERT INTO sujatabyidandage  (id, roll_number, age) 
                             VALUES (2, 20, 26);
aploetz@cqlsh:stackoverflow> INSERT INTO sujatabyidandage  (id, roll_number, age) 
                             VALUES (1, 100, 24);
aploetz@cqlsh:stackoverflow> INSERT INTO sujatabyidandage  (id, roll_number, age) 
                             VALUES (1, 110, 24);
aploetz@cqlsh:stackoverflow> INSERT INTO sujatabyidandage  (id, roll_number, age) 
                             VALUES (1, 190, 24);

现在我可以运行您的查询,我不需要指定 ORDER BY 或 ALLOW FILTERING:

aploetz@cqlsh:stackoverflow> SELECT COUNT(*) FROM sujatabyidandage WHERE ID=1 AND age=24;

 count
-------
     3

(1 rows)

另外值得一提的是,如果结果集顺序对您很重要,那么您必须按主键查询。 Cassandra 仅在分区键(在您的情况下为 ID)中强制执行结果顺序。

【讨论】:

  • 您的建议似乎不错。但我想要使用非主键的查询。如果不可能,则查询可能导致错误,但它向​​我显示了一些缺少的 EOF。你能告诉我我在哪里失踪吗?
  • @sujata 我的第二点详细说明了导致您的 EOF 的原因。 CQL 期望您的声明在 ORDER BY 结束,但在它之后您有 AND
  • @sujata 你也可以通过不指定ORDER BY 来修复它(我在第三点中提到过)。
  • 我没有在我的表定义中指定排序顺序,因为我已经阅读了 cassandra 默认按升序对数据进行排序。根据文档,如果我在查询中指定 order by,则行的检索效率更高且更快。
  • 如果我的查询是 SELECT count(*) FROM sujata WHERE ID=1 ORDER BY roll_number ASC,那么获取 600000 行所需的时间仅为 19 秒,而查询 SELECT count(*) FROM sujata WHERE ID=1 and age=24 获取 160000 行需要大约 56 秒。为什么时间差这么大??
猜你喜欢
  • 2015-11-29
  • 1970-01-01
  • 2013-09-02
  • 2015-10-01
  • 2016-04-05
  • 1970-01-01
  • 2020-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多