错误请求:带有等于运算符的by-columns子句中没有索引列:CQL错误?

时间:2013-11-03 18:24:39

标签: cassandra cql cql3

我在CQL中有下表 -

create table test (
    employee_id text,
    employee_name text,
    value text,
    last_modified_date timeuuid,
    primary key (employee_id)
   );

我在上表中插入了几条记录,我将在实际用例场景中插入这些记录 -

insert into test (employee_id, employee_name, value, last_modified_date) values ('1', 'e27',  'some_value', now());
insert into test (employee_id, employee_name, value, last_modified_date) values ('2', 'e27',  'some_new_value', now());
insert into test (employee_id, employee_name, value, last_modified_date) values ('3', 'e27',  'some_again_value', now());
insert into test (employee_id, employee_name, value, last_modified_date) values ('4', 'e28',  'some_values', now());
insert into test (employee_id, employee_name, value, last_modified_date) values ('5', 'e28',  'some_new_values', now());

现在我正在进行选择查询 - 为employee_name e27提供所有employee_id。

select employee_id from test where employee_name = 'e27';

这是我得到的错误 -

Bad Request: No indexed columns present in by-columns clause with Equal operator
Perhaps you meant to use CQL 2? Try using the -2 option when starting cqlsh.

我在这里做错了吗?

我的使用案例一般 -

  1. 给我任何employee_name的一切?
  2. 告诉我最近5分钟内发生了什么变化?
  3. 向我提供任何employee_name的最新employee_id和值?
  4. 为我们提供employee_name的所有employee_id吗?
  5. 我正在运行Cassandra 1.2.11

2 个答案:

答案 0 :(得分:24)

一般规则很简单:“您只能通过属于密钥一部分的列进行查询”。作为解释,所有其他查询都需要对表进行完整扫描,这可能意味着需要进行大量数据筛选。

有些东西可以修改此规则:

  1. 对基数较低的列使用二级索引(更多详情here
  2. 定义多列密钥(例如PRIMARY KEY (col1, col2);这将允许col1 = value1col1 = value1 and col2 COND等查询
  3. 在查询中使用ALLOW FILTERING。这将导致警告,因为Cassandra将不得不筛选大量数据,并且不会有性能保证。有关详细信息,请参阅details of ALLOW FILTERING in CQLthis SO thread

答案 1 :(得分:16)

Cassandra稍微习惯了:)我们中的一些人已经被RDBMS为你做的一些额外的东西所破坏,你没有从noSql免费获得。

如果您回想一下常规的RDBMS表,如果您在没有索引的列上进行SELECT,则数据库必须执行全表扫描才能找到您寻找的所有匹配项。这是卡桑德拉的禁忌,如果你试图这样做,它会抱怨。想象一下,如果您在此查询中找到10 ^ 32个匹配项?这不是一个合理的问题。

在您的表中,您已编码* PRIMARY KEY(employee_id); *这是行的主要和唯一标识键。 您现在可以从TEST中选择employee * id ='123'; 这是完全合理的,Cassandra会很高兴地返回结果。

但是,你的 SELECT来自TEST WHERE employee_name ='e27'; 告诉Cassandra去读取每条记录,直到找到'e27'匹配为止。没有索引依赖,它礼貌地要求你“忘记它”。

如果要对列进行过滤,请确保在该列上有索引,以便Cassandra可以执行所需的过滤。