如何通过end_block_num和public_key两个二级索引高效获取RethinkDB匹配记录
RethinkDB多二级索引查询优化方案
现有方案对比
- 第一种
filter方案
该方案不会利用你创建的二级索引,会执行全表扫描逐行匹配条件,数据量较大时性能极差,不推荐使用。另外注意你代码中存在字段拼写错误:r.row["public_ket"]应为public_key,会导致查询结果不符合预期。 - 第二种
get_all+set_union方案
该方案正确使用了两个二级索引,避免了全表扫描,效率远高于第一种方案,你的判断是正确的。但该写法存在可优化空间:coerce_to("array")会先将两次查询的全量结果加载到内存再做并集计算,会产生不必要的内存占用和序列化开销。
最优实现方案
场景1:需要两个条件满足任意其一(OR逻辑,即你当前代码的逻辑)
直接使用union方法替换coerce_to("array")+set_union的组合,查询会在RethinkDB服务端流式处理结果,不需要提前加载全量数据,性能更高:
# 不需要去重的场景(确认没有记录同时满足两个条件) agents = ( r.table("agents") .get_all(1000, index="end_block_num") .union(r.table("agents").get_all("AABBCC", index="public_key")) .run(conn) ) # 需要去重的场景(可能存在同时满足两个条件的记录) agents = ( r.table("agents") .get_all(1000, index="end_block_num") .union(r.table("agents").get_all("AABBCC", index="public_key")) .distinct() .run(conn) )
场景2:需要同时满足两个条件(AND逻辑)
如果你的实际需求是取两个条件的交集,最高效的方式是新建一个联合二级索引:
# 建索引操作,只需执行一次 r.table("agents").index_create("end_block_public_key", [r.row["end_block_num"], r.row["public_key"]]).run(conn) r.table("agents").index_wait("end_block_public_key").run(conn)
后续查询直接走联合索引,一次查询即可拿到结果:
agents = r.table("agents").get_all([1000, "AABBCC"], index="end_block_public_key").run(conn)
内容的提问来源于stack exchange,提问作者Charalarg
相关产品推荐
相关产品推荐

