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

Most efficient way to get first N rows matching some criterion on ordinary (not clustering) columns

我想return Cassandra 数据库的前 N ​​行根据某些标准进行过滤,其中过滤是在 普通(非聚类)列上完成的。

让我们假设一个简单的 table 像这样:

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=?

一次读取结果一页,一旦读取了足够多的 suitable 行就停止读取。是否有任何与尚未获取的页面相关的费用?如果不是,我猜这是明显的赢家。

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

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

如果结果中的 suitable 行不足,则在上一个查询结果的最后一个 timestamp.

之后开始发出新查询

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

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

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

我最大的惊喜是分页单个大查询的结果比多个小查询的串行执行(即 non-concurrent)好不了多少。难道每次驱动程序请求下一页结果时,Cassandra 实际上都会对该页面执行新的查询?

显然,这些结论因所查询的数据集而存在严重偏差。然而,ALLOW FILTERING 的优势是如此明显,以至于我会做出工作假设这将适用于几乎所有情况。