cassandra:如何在没有eq或in限制主键的情况下使用“order by”?

csbfibhn  于 2021-06-10  发布在  Cassandra
关注(0)|答案(2)|浏览(447)

我在scylla(与cassandra兼容的数据库)中有一个表,定义如下:

create table s.items (time timeuuid, name text, primary key (time));

我想运行一个查询,在一段时间后获取所有项目,如下所示:

select * from s.items where time>7e204790-43bf-11e9-9759-000000000004 order by time asc;

但有人告诉我 ORDER BY is only supported when the partition key is restricted by an EQ or an IN. 为了解决这个问题,我可以创建一个类似于以下内容的表和查询:

create table s.items (yes boolean, time timeuuid, name text, primary key (yes, time));

select * from s.items where yes=true and time>7e204790-43bf-11e9-9759-000000000004 order by time asc;

虽然这是可行的,但似乎不是最好的解决方案。因为我对锡拉和cql还比较陌生,有没有更好的/合适的方法?

ggazkfy8

ggazkfy81#

类似的问题也得到了回答。例如:cassandra数据建模:时间戳作为分区键
您需要设计一个适当的分区键,根据预期的数据量,可能是一年

mbjcgjjk

mbjcgjjk2#

添加一个布尔键并始终将其设置为yes的解决方案基本上会创建一个包含所有数据的巨大分区。这很少是你真正想要的。如果这一个分区是您的全部数据,这意味着即使您有一个10节点的集群,每个节点上有8个cpu,但集群中所有80个cpu中只有3个cpu将执行任何工作(因为每个分区属于某个cpu,并且rf=3时有三个副本)。
如果您想知道为什么原来的解决方案不起作用,而scylla拒绝了“order by”,那么问题是,尽管scylla可以扫描整个表以在时间x之后查找条目(您需要在查询中添加“allow filtering”),但它没有按时间对查找到的内容进行排序的有效方法。在内部,不同的分区不是按分区键排序的,而是按分区键的哈希函数“token”排序的。这种散列及其随机化效应对于平衡集群上所有cpu之间的负载非常重要,但会阻止scylla(或cassandra)以原始键顺序读取分区。
您可以做的一件事是按照alex的建议去做,这是您最初的设置和建议的解决方案之间的一个中间地带:不要每个分区都有一个项目,或者所有的项目都在一个分区中,而是中间地带:例如,想象一下,在您的工作负载中,每天都收集100mb的数据。因此,您使用天数作为分区键(而不是bool)。某一天的所有数据都将放在一个分区中。在每天的分区中,不同的条目(行)将按集群键顺序(即时间)排序。使用此设置,要在某个特定日期之后检索所有项目,只需开始逐个查询每个单独的日期。e、 例如,查询第134天,然后查询第135天,然后查询第136天,等等。。。在每一天内,结果都会被排序。所以问题解决了。
这种技术是相当有名的“时间序列”数据建模。scylla(和cassandra)甚至有一个为这种建模调整的特殊压缩策略,twcs(时间窗口压缩策略)。

相关问题