如何在没有分区键的情况下使用order\u by搜索记录

oaxa6hgo  于 2021-06-14  发布在  Cassandra
关注(0)|答案(1)|浏览(362)

我正在调试一个问题,日志应该位于4/23/19到4/25/19之间的时间范围内
我们制作的唱片有上亿张。使用随机排序无法定位目标记录。
在没有分区键的时间范围内搜索有什么解决方法吗?
从x中选择*按说明中修改的汇总顺序报告

架构

...
"modified_at"   "TimestampType" "regular"
"record_end_date"   "TimestampType" "regular"
"record_entity_type"    "UTF8Type"  "clustering_key"
"record_frequency"  "UTF8Type"  "regular"
"record_id" "UUIDType"  "partition_key"
piztneat

piztneat1#

第一, ORDER BY 在Cassandra真的是多余的。它只能对分区内的群集列进行操作,然后只能对群集列的确切顺序进行操作。原因是cassandra按顺序从磁盘读取数据,因此它首先按照定义的集群顺序写入所有数据。
所以在我看来, ORDER BY 在cassandra中,除了要更改排序方向(升序/降序)的情况外,它是非常无用的。
其次,由于它的分布式特性,您需要采用面向查询的方法来进行数据建模。换句话说,表的设计必须支持要运行的查询。现在您可以找到解决这个问题的方法,但是您基本上是在分布式集群上执行完整的表扫描,这对任何人来说都不会有好的结果。
因此,建议的方法是构建如下表:

CREATE TABLE stackoverflow.report_summary_by_month (
    record_id uuid,
    record_entity_type text,
    modified_at timestamp,
    month_bucket bigint,
    record_end_date timestamp,
    record_frequency text,
    PRIMARY KEY (month_bucket, modified_at, record_id)
) WITH CLUSTERING ORDER BY (modified_at DESC, record_id ASC);

然后,此查询将工作:

SELECT * FROM report_summary_by_month
WHERE month_bucket = 201904 
AND modified_at >= '2019-04-23' AND modified_at < '2019-04-26';

这里的想法是,当你关心结果的顺序时,你需要用其他的东西来划分,以允许排序工作。在本例中,我选择了月份,因此我将您的结果按月份“扣”到一个名为 month_bucket . 每个月,我都在 modified_atDESC 结束顺序。这样,最新的结果就位于分区的“顶部”。然后,我投了进去 record_id 作为打破僵局的关键,有助于确保独特性。
如果你仍然专注于以错误的方式做这件事:
实际上,可以在当前架构上运行范围查询。但是,由于“数亿条记录”跨越多个节点,我对这一点不抱太大希望。但你可以用 ALLOW FILTERING 指令(你不应该真正使用)。

SELECT * FROM report_summary
WHERE modified_at >= '2019-04-23'
AND modified_at < '2019-04-26' ALLOW FILTERING;

这种方法有以下注意事项:
由于跨多个节点有许多记录,它可能会超时。
如果无法为该查询标识单个分区,则会选择协调器节点,并且该节点很有可能过载。
由于这是从多个分区中提取行,因此无法强制执行排序顺序。 ALLOW FILTERING 使Cassandra的工作方式,它真的不是设计的,所以我永远不会用在生产系统。
如果您真的需要运行这样的查询,我建议您使用内存中的聚合工具,比如spark。
还有,原来的问题是 ORDER BY ,不久前我写了一篇文章,更好地解释了这个主题:https://www.datastax.com/dev/blog/we-shall-have-order

相关问题