【问题标题】:Cassandra asks for ALLOW FILTERING even though column is clustering keyCassandra 要求允许过滤,即使列是集群键
【发布时间】:2016-07-13 11:37:10
【问题描述】:

对 Cassandra 非常陌生,如果问题很简单,敬请见谅。

我创建了一个表:

create table ApiLog (
LogId uuid,     
DateCreated timestamp,
ClientIpAddress varchar,
primary key (LogId, DateCreated));

这项工作很好:

select * from apilog

如果我尝试像这样添加带有 DateCreated 的 where 子句:

select * from apilog where datecreated <= '2016-07-14'

我明白了:

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

从关于 SO 的其他问题和关于 datastax 的教程中,我了解到,由于 datecreated 列是一个聚类键,它可以用来过滤数据。

我也尝试创建索引,但我得到了相同的消息。我试图从主键中删除 DateCreated 并将其仅作为索引,但我仍然得到相同的结果:

create index ApiLog_DateCreated on dotnetdemo.apilog (datecreated);

【问题讨论】:

    标签: cassandra


    【解决方案1】:

    分区键 LogId 确定每个分区将存储在哪个节点上。所以如果不指定分区键,那么 Cassandra 就得在所有节点上过滤这个表的所有分区,才能找到匹配的数据。这就是为什么您必须说 ALLOW FILTERING 的原因,因为该操作效率非常低且不鼓励。

    如果你指定一个特定的LogId,那么Cassandra可以在单个节点上找到分区,并通过集群键高效地进行范围查询。

    因此,您需要规划架构,以便可以在单个分区内进行范围查询,而不必像您尝试那样进行全表扫描。

    【讨论】:

    • 那么我是否正确地假设拥有一个包含 uuid 作为分区键的 PK 总是一个坏主意,因为您永远无法有效地查询数据?
    • 是的,这通常是个坏主意,因为您的分区中只有一行。这仅在您的应用程序需要一次处理一行时才有用。
    • 我现在明白了。我想从 RDBMS 来时需要一些时间来以不同的方式思考,谢谢。
    猜你喜欢
    • 2020-07-19
    • 2020-12-01
    • 2017-07-23
    • 2019-01-13
    • 1970-01-01
    • 2017-12-20
    • 2023-03-10
    • 2015-05-07
    • 2020-10-12
    相关资源
    最近更新 更多