在 CQL 中,您可以应用WHERE
一旦为所有列创建了索引(即二级索引),就可以在所有列上使用子句。否则,您将收到以下错误:
Bad Request: No indexed columns present in by-columns clause with Equal operator
不幸的是,即使有二级索引,CQL 也要求 WHERE 子句在二级索引上至少有一个 EQ,因为性能问题.
问:为什么总是需要至少进行一次 EQ 比较
二级指标?
答:二级指标的不平等总是存在的
在内存中完成,因此在另一个二级索引上至少没有一个 EQ
您将加载数据库中的每一行,其中有大量
数据库不是一个好主意。因此,通过要求至少一个 EQ
(辅助)索引,您希望限制需要读入的行集
内存到可管理的大小。 (虽然显然你仍然可以得到
也陷入麻烦)。
因此,基本上,如果您除了 EQ 比较之外还有其他任何内容,它都会加载“否则与您的查询匹配”的所有行,并检查它们是否匹配,一次一个。默认情况下不允许这样做,因为它“可能会很慢”。 (本质上,索引只是“为了平等”而索引,而不是像关系数据库上的索引那样的 之类的其他索引)。
需要注意的一件事是,如果二级指数中有多个非 EQ 条件,则还需要包括ALLOW FILTERING
查询中的关键字,否则您将得到
Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING
一种简单的解决方法是将虚拟列附加到表中,其中所有行在该列上都具有相同的值。因此,在这种情况下,您可以仅对所需的列执行范围查询。请认识到,NoSQL 数据库上的此类查询可能会减慢/使系统陷入困境。
Example
cqlsh:demo> desc table table1;
CREATE TABLE table1 (
keya int,
keyb int,
dummyvalue int,
valuea int,
PRIMARY KEY (keya, keyb)
) ....
cqlsh:demo> select * from Table1;
keya | keyb | dummyvalue | valuea
------+------+------------+--------
1 | 2 | 0 | 3
4 | 5 | 0 | 6
7 | 8 | 0 | 9
在 ValueS 和 Dummy Value 上创建二级索引:
cqlsh:demo> create index table1_valuea on table1 (valuea);
cqlsh:demo> create index table1_valueb on table1 (dummyvalue);
执行范围查询ValueA
with DummyValue=0
:
cqlsh:demo> select * from table1 where dummyvalue = 0 and valuea > 5 allow filtering;
keya | keyb | dummyvalue | valuea
------+------+------------+--------
4 | 5 | 0 | 6
7 | 8 | 0 | 9