16

我在 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_id 的 employee_name e27

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_id 和任何employee_name 的值?
  4. 给我任何employee_name 的所有employee_id 吗?

我正在运行 Cassandra 1.2.11

4

2 回答 2

24

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

有一些东西可以修改这个规则:

  1. 对具有低基数的列使用二级索引(更多细节在这里
  2. 定义多列键(例如PRIMARY KEY (col1, col2); 这将允许像col1 = value1and之类的查询col1 = value1 and col2 COND
  3. ALLOW FILTERING在查询中使用。这将导致警告,因为 Cassandra 将不得不筛选大量数据并且没有性能保证。有关更多详细信息,请参阅CQL 中的 ALLOW FILTERING此 SO 线程的详细信息
于 2013-11-04T05:47:18.810 回答
16

Cassandra 需要一点时间来适应 :) 我们中的一些人已经被 RDBMS 为您提供的一些额外的东西宠坏了,而这些额外的东西并不是您从 noSql 中免费获得的。

如果您回想一下常规的 RDBMS 表,如果您在没有索引的列上进行 SELECT,则数据库必须执行全表扫描以找到您寻找的所有匹配项。这在 Cassandra 中是一个禁忌,如果您尝试这样做,它会抱怨。想象一下,如果您发现 10^32 匹配此查询?这不是一个合理的要求。

在您的表中,您已编码 *PRIMARY KEY(employee_id);* 这是该行的主要和唯一标识键。 您现在可以 SELECT * from TEST where employee_id='123'; 这是完全合理的,Cassandra 会很乐意返回结果。

但是,您的SELECT from TEST WHERE employee_name = 'e27'; 告诉 Cassandra 去阅读每条记录,直到在“e27”上找到匹配项。由于没有可依赖的索引,它礼貌地要求您“忘记它”。

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

于 2013-11-04T22:10:21.490 回答