【问题标题】:Cassandra Allow filteringCassandra 允许过滤
【发布时间】:2017-07-23 09:43:53
【问题描述】:

我有一张如下表

CREATE TABLE test (
 day int,
 id varchar,  
 start int,
 action varchar,  
 PRIMARY KEY((day),start,id)
);

我想运行这个查询

Select * from test where day=1 and start > 1475485412 and start < 1485785654 
and action='accept' ALLOW FILTERING

允许过滤有效吗?

我希望 cassandra 会按此顺序过滤

1. By Partitioning column(day)
2. By the range column(start) on the 1's result
3. By action column on 2's result. 

因此,允许过滤不会是此查询的错误选择。

如果where子句上有多个过滤参数并且非索引列是最后一个,过滤器将如何工作? 请解释一下。

【问题讨论】:

标签: cassandra datastax cql datastax-enterprise


【解决方案1】:

这是否允许过滤有效?

当您写“this”时,您的意思是在查询和模型的上下文中,但是 ALLOW FILTERING 查询的效率主要取决于它必须过滤的数据。除非您提供一些真实数据,否则这是一个很难回答的问题。

我希望 cassandra 会按此顺序过滤...

是的,这就是将要发生的事情。但是,在查询中包含 ALLOW FILTERING 子句通常意味着糟糕的表设计,即您没有遵循 Cassandra 建模的一些准则(特别是“一个查询 一个表”)。

作为一种解决方案,我可以提示您将 action 字段包含在 start 字段之前的集群键中,从而修改您的表定义:

CREATE TABLE test (
 day int,
 id varchar,  
 start int,
 action varchar,  
 PRIMARY KEY((day),action,start,id)
);

然后您将在没有任何 ALLOW FILTERING 子句的情况下重写您的查询:

SELECT * FROM test WHERE day=1 AND action='accept' AND start > 1475485412 AND start < 1485785654

只有 次要 问题,如果一条记录“切换”action 值,您无法对单个 action 字段执行更新(因为它现在是集群键的一部分),所以您需要使用旧的 action 值执行删除,然后使用正确的新值插入它。但是,如果您拥有 Cassandra 3.0+,所有这一切都可以在新的物化视图实现的帮助下完成。如需更多信息,请联系look at the documentation

【讨论】:

  • 如果查询是按照我说的顺序扫描磁盘,那么允许过滤是不错的选择。因为它只过滤有限数量的数据。
  • @Bharathi:你也想扫描墓碑吗?我们对您的数据一无所知,因此这里的一般建议是“不要使用 ALLOW FILTERING”,但如果您认为您有少量记录,请继续使用它。毕竟,使用大脑绝对是在 Cassandra 中建模的最佳方式……
  • 我只是想了解允许过滤。我的用例与我在这里所说的不完全相同,我不能在这里公开。我想知道,如果 cassandra 按我所说的顺序过滤,就不用担心它要扫描的数据量。
  • @xmas79 有没有办法避免扫描墓碑?
  • @soote 唯一的方法是避免删除,因此您只扫描实时数据。如果您想“跳过”无用数据,请更改模型并提高查询效率。如果你不能(前两者),等待压缩...
【解决方案2】:

一般 ALLOW FILTERING 效率不高。

但最终它取决于您要获取的数据的大小(cassandra 必须为此使用ALLOW FILTERING)以及从中获取数据的大小。

在您的情况下,cassandra 不需要过滤:

  1. 按范围列(开始)对 1 的结果

正如你所说。但在那之后,它将依赖过滤来搜索数据,您在查询本身中允许这样做。

现在,请记住以下内容

如果您的表包含例如 100 万行并且其中 95% 具有请求的值,则查询仍然相对有效,您应该使用 ALLOW FILTERING。

另一方面,如果您的表包含 100 万行,而只有 2 行包含请求的值,则您的查询效率极低。 Cassandra 将加载 999、998 行。如果经常使用查询,最好在time1列上加一个索引。

所以首先确保这一点。如果它对您有利,请使用过滤。 否则,明智的做法是在 'action' 上添加二级索引。

PS:有一些小的修改。

【讨论】:

  • 我在不同的问题上阅读了相同的答案。这不是这个问题的答案。如果您知道,请具体说明查询的工作方式。
  • 我不知道这个问题,但我在这个旧的datastax doc 上读到了这个。看看它。虽然我仍然认为我的回答很好地解释了它。但是,如果您发现其他情况,请在此处提及。也会消除我的误解(如果有的话)。谢谢!
  • 感谢您的更新。我知道 ALLOW FILTERING 将扫描整个列族。但是这里的问题是,如果 where 子句上有多个过滤参数并且非索引列是最后一个,那么过滤器将如何工作?请阅读问题并让我知道它是否需要任何编辑以便更好地理解。
猜你喜欢
  • 2019-01-13
  • 2023-03-10
  • 2015-05-07
  • 2020-10-12
  • 2021-09-10
  • 2016-08-14
  • 2017-12-20
  • 2013-09-02
  • 1970-01-01
相关资源
最近更新 更多