我尝试选择在索引列中包含至少一个具有特定值的行的分区键。
在目前的解决方案中,所有其他要求都得到满足:
最后,我需要选择某个用户创建报告的所有办公室的能力。基于cassadra文档,我在用户列中添加了一个索引。
该表被定义为:
create table report(
office uuid,
type text,
insert_date timestamp,
...
created_by uuid,
...
primary key(office, type, insert_date));
create index created_by_idx on report (created_by);如果我没有错的话,使用该索引就像有一个二级表,描述如下:
create table report2(
created_by uuid,
office uuid,
type text,
insert_date timestamp,
...
primary key(created_by ,office, type, insert_date));我可以成功地运行类似于:select office from report where created_by = ?的查询,但是这会导致具有相同office键的多行,这是正确的:每个用户都可以在每个office中创建多个报告。
现在我在软件层面对重复的办公室进行过滤,但我在问自己,在提取过程中是否可以直接过滤这些数据。
我试过:select distinct office from report where created_by = ?,这会导致SELECT DISTINCT with WHERE clause only supports restriction by partition key and/or static columns.
然后我尝试:select office from report where created_by = ? group by office,它给了我正确的结果,但是引发了一个警告:Aggregation query used without partition key
这会不会是个问题?在这种情况下,如何处理cassandra这样的查询,是否可以忽略此警告?最后,一个更好的选择是对select * ...使用这样的查询,它具有相同的where子句吗?
发布于 2019-01-10 20:53:48
卡桑德拉不支持你描述的特性是有原因的--因为它可能效率低下:
首先,正如您所提到的,辅助索引必须列出所有匹配的行键,而不仅仅是不同的匹配分区键。这是因为您可以请求所有的行,而不仅仅是不同的分区键,所以数据必须在那里。必须将这些数据保存在索引中的另一个原因是,每个单独的行都可能被单独删除(或过期),因此Cassandra需要跟踪所有这些数据,以确定整个分区是否仍然存在,或者不再存在。
现在,由于搜索结果列表中已经列出了所有行的键,所以只输出“不同”的分区键是一种低效率的操作.如果在一个分区中有一百万行匹配,那么Cassandra将需要扫描所有这些行,然后才能输出一个结果。Cassandra通常不允许用户使用低效操作(例如,查看如何使用“允许过滤”来显式地允许在SELECT查询中进行低效过滤)。
尽管如此,未来的Cassandra版本应该允许您请求的“选择不同”请求,这是有意义的,也许需要用户说“允许过滤”来承认它可能很慢。另外,另一种实现可能涉及较慢的更新(每行更新将检查分区的活性),但随后会快速读取。Scylla考虑过这样的实现,但也没有实现(参见https://github.com/scylladb/scylla/issues/3435)。
https://stackoverflow.com/questions/54108695
复制相似问题