cassandra通过聚类键选择

时间:2017-08-08 10:33:28

标签: cassandra scylla

我遇到了cassandra的问题(ScyllaDB(不支持索引!))

在我的场景中,我有一个包含三列的表

CREATE TABLE test (a text , b text , c text , PRIMARY KEY ( a , b ,c ) );

现在我想通过第二个群集密钥选择数据(c) 但是需要b。

我的目标但不正确的查询是:

SELECT * FROM test WHERE c='...' ALLOW FILTERING

正确的查询是:

SELECT * FROM test WHERE b='...' AND c='...' ALLOW FILTERING

我的问题是否有任何解决方案只在select查询中使用b群集密钥?

2 个答案:

答案 0 :(得分:4)

您可以查询

  • a SELECT * FROM test WHERE a='...'
  • a和b SELECT * FROM test WHERE a='...' AND b='...'
  • a和b和c SELECT * FROM test WHERE a='...' AND b='...' AND c='...'

但不是a和c。这是因为您需要按照定义的顺序使用分区键+零个或多个聚类键。

化妆品:在CREATE TABLE中不需要() a左右,因为您不应用复合分区键:

CREATE TABLE test (a text, b text, c text, PRIMARY KEY (a, b, c))

答案 1 :(得分:1)

正如其他人已经指出的那样,Cassandra在跳过部分群集密钥时不支持过滤。虽然人们很容易将此视为一种限制,但深入研究这种限制存在的原因是有帮助的。

首先,ALLOW FILTERING子句已经强调集群中Cassandra节点的全部。由于查询未指定分区键,因此每个节点都必须通过从磁盘加载数据并丢弃不符合提供条件的记录来处理它。但据我所知,由于Cassandra在文件中存储数据的方式,它只能根据查询中提供的聚类键加载其子集。但是,仅当指定了聚类键的所有组件时,或者只省略了一个或多个最后组件时。

如果查询"跳过"集群密钥的一部分,就像你的例子中一样,每个节点都必须从文件系统加载几乎所有东西,然后依次寻找匹配。您可以想象后果,即使过滤器匹配的实际记录数量可以忽略不计。

This帖子更详细地解释了ALLOW FILTERING的影响,而this one更深入地探讨了SQL WHERE条款。

可能的解决方案

我确信知道此限制并不能解决您能够通过分区键的c组件进行查询的问题。据我所知,修改数据模型通常会提供更好的解决方案。

如果您发现自己经常按c查找数据,请再添加一个表,其中c将成为分区键。您不仅可以获得缓存和有限数据加载的所有好处,而且还可以将查询限制为仅一个节点。执行时间的改进通常会超过您尝试定制过滤查询时可能获得的磁盘空间节省。