我想按某种标准从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
之后开始执行新的查询。
我想知道什么可能是最好的选择。
答案 0 :(得分:0)
我做了一些现成的基准测试。令我惊讶的是,我发现ALLOW FILTERING
选项至少在我的测试场景中快了几个数量级。其他两个选项在很大程度上取决于LIMIT
或页面大小,而较小的LIMIT
/页面则表现得非常差。
如果在第一页/第一个查询结果中找到第一行,那么这三个选项相差不远,但是ALLOW FILTERING
仍然 最快。
让我最大的惊喜是,对单个大查询的结果进行分页的效果比对多个小查询的串行执行(即非并发)要好。可能是驱动程序每次请求下一页结果时,Cassandra实际上都对该页执行了新查询吗?
很明显,这些结论由于所查询的数据集而有很大偏差。但是,ALLOW FILTERING
的优越性是如此明显,以至于我做出了一个可行的假设,即这几乎适用于所有情况。