最有效的方式来获取与普通(非聚类)列上的某些条件匹配的前N行

时间:2019-06-12 15:33:00

标签: cql cassandra-3.0

我想按某种标准从Cassandra数据库过滤返回前N行,其中过滤是在普通(而不是聚类)列上完成的。

我们假设一个简单的表是这样的:

CREATE TABLE test(
  id UUID,
  timestamp TIMESTAMP,
  value DOUBLE,
  PRIMARY KEY ((id), timestamp)
) WITH CLUSTERING ORDER BY (timestamp ASC)

选项1

SELECT timestamp, value FROM test WHERE id=? AND value<? LIMIT ? ALLOW FILTERING

这是允许的,但是通常应避免使用ALLOW FILTERING。话虽这么说,如果查询仅触及一个分区真的很糟糕吗?

选项2 设置非常小的分页大小,例如N * 10(例如),然后:

SELECT timestamp, value FROM test WHERE id=?

一次读取一页结果,并在读取足够的合适行后立即停止读取。与尚未提取的页面相关的任何费用吗?如果没有,我想这显然是赢家。

选项3 默认分页,将结果数限制为N * 10,如果返回的合适行不足,则发出新查询:

SELECT timestamp, value FROM test WHERE id=? AND timestamp>? LIMIT ?

如果结果中没有合适的行,请在前一个查询结果的最后一个timestamp之后开始执行新的查询。

我想知道什么可能是最好的选择。

1 个答案:

答案 0 :(得分:0)

我做了一些现成的基准测试。令我惊讶的是,我发现ALLOW FILTERING选项至少在我的测试场景中快了几个数量级。其他两个选项在很大程度上取决于LIMIT或页面大小,而较小的LIMIT /页面则表现得非常差。

如果在第一页/第一个查询结果中找到第一行,那么这三个选项相差不远,但是ALLOW FILTERING仍然 最快。

让我最大的惊喜是,对单个大查询的结果进行分页的效果比对多个小查询的串行执行(即非并发)要好。可能是驱动程序每次请求下一页结果时,Cassandra实际上都对该页执行了新查询吗?

很明显,这些结论由于所查询的数据集而有很大偏差。但是,ALLOW FILTERING的优越性是如此明显,以至于我做出了一个可行的假设,即这几乎适用于所有情况。