cassandra select 通过聚类键
cassandra select by clustering key
我对 cassandra 有疑问(ScyllaDB(不支持索引!))
在我的场景中,我有一个 table 三列
CREATE TABLE test (a text , b text , c text , PRIMARY KEY ( a , b ,c ) );
现在我想 select 通过第二个簇键 ( c ) 获取数据
但需要 b。
我的目标但不正确的查询是:
SELECT * FROM test WHERE c='...' ALLOW FILTERING
正确的查询是这样的:
SELECT * FROM test WHERE b='...' AND c='...' ALLOW FILTERING
对于我的问题是否有任何解决方案可以在 select 查询中仅使用 b 簇键?
您可以查询
- 一个
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))
正如其他人已经指出的那样,Cassandra 不支持在跳过部分集群键时进行过滤。虽然很容易将此视为限制,但深入了解此限制存在的原因是有帮助的。
首先,ALLOW FILTERING
子句已经对集群中的 all Cassandra 节点施加了压力。由于查询未指定分区键,因此每个节点都必须通过从磁盘加载数据并丢弃与提供的条件不匹配的记录来处理它。但据我所知,由于 Cassandra 在文件中存储数据的方式,它只能根据查询中提供的集群键加载其子集。但是,只有指定了聚类键的所有组件,或者仅省略了 last 中的一个或多个组件。
如果查询 "skips" 部分集群键,就像在您的示例中一样,每个节点都必须从文件系统加载几乎所有内容,然后依次查找匹配项。你可以想象后果,即使过滤器匹配的实际记录数可以忽略不计。
This post explains in more details the impact of ALLOW FILTERING
while this one 深入探讨了 SQL WHERE
子句的一般情况。
可能的解决方案
我敢肯定,了解此限制并不能解决您无法通过分区键的 c
组件进行查询的问题。据我所知,修改数据模型通常会提供更好的解决方案。
如果您发现自己经常通过 c
查找数据,请再添加一个 table,其中 c
将成为分区键。您不仅将获得缓存和有限数据加载的所有好处,而且还将查询限制为仅一个节点。执行时间的改进通常会超过磁盘上的任何节省 space,您可能会尝试定制过滤查询。
总的来说,Scylla 旨在实现与 Cassandra 的功能对等。为此,Scylla 对集群键过滤的限制与 Cassandra 的相同(此线程中的其他评论适用)。 Scylla 2.0 RC1 将很快发布,带来物化视图的实验版本。您可以在此处了解 2.0 RC1 版本将支持和不支持的内容:http://www.scylladb.com/2017/07/27/materialized-views-preview-scylla-2-0/ .
我对 cassandra 有疑问(ScyllaDB(不支持索引!))
在我的场景中,我有一个 table 三列
CREATE TABLE test (a text , b text , c text , PRIMARY KEY ( a , b ,c ) );
现在我想 select 通过第二个簇键 ( c ) 获取数据 但需要 b。
我的目标但不正确的查询是:
SELECT * FROM test WHERE c='...' ALLOW FILTERING
正确的查询是这样的:
SELECT * FROM test WHERE b='...' AND c='...' ALLOW FILTERING
对于我的问题是否有任何解决方案可以在 select 查询中仅使用 b 簇键?
您可以查询
- 一个
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))
正如其他人已经指出的那样,Cassandra 不支持在跳过部分集群键时进行过滤。虽然很容易将此视为限制,但深入了解此限制存在的原因是有帮助的。
首先,ALLOW FILTERING
子句已经对集群中的 all Cassandra 节点施加了压力。由于查询未指定分区键,因此每个节点都必须通过从磁盘加载数据并丢弃与提供的条件不匹配的记录来处理它。但据我所知,由于 Cassandra 在文件中存储数据的方式,它只能根据查询中提供的集群键加载其子集。但是,只有指定了聚类键的所有组件,或者仅省略了 last 中的一个或多个组件。
如果查询 "skips" 部分集群键,就像在您的示例中一样,每个节点都必须从文件系统加载几乎所有内容,然后依次查找匹配项。你可以想象后果,即使过滤器匹配的实际记录数可以忽略不计。
This post explains in more details the impact of ALLOW FILTERING
while this one 深入探讨了 SQL WHERE
子句的一般情况。
可能的解决方案
我敢肯定,了解此限制并不能解决您无法通过分区键的 c
组件进行查询的问题。据我所知,修改数据模型通常会提供更好的解决方案。
如果您发现自己经常通过 c
查找数据,请再添加一个 table,其中 c
将成为分区键。您不仅将获得缓存和有限数据加载的所有好处,而且还将查询限制为仅一个节点。执行时间的改进通常会超过磁盘上的任何节省 space,您可能会尝试定制过滤查询。
总的来说,Scylla 旨在实现与 Cassandra 的功能对等。为此,Scylla 对集群键过滤的限制与 Cassandra 的相同(此线程中的其他评论适用)。 Scylla 2.0 RC1 将很快发布,带来物化视图的实验版本。您可以在此处了解 2.0 RC1 版本将支持和不支持的内容:http://www.scylladb.com/2017/07/27/materialized-views-preview-scylla-2-0/ .