可能有几种方法可以对此进行优化。
在 CQEngine 中,我倾向于使用术语ordering 来描述期望的结果,然后可以有多种排序策略来实现排序。
CQEngine 中的默认行为是使用所谓的materialize 排序策略,这涉及将匹配查询的所有结果复制到一个临时集合中,然后显式排序。这不能很好地扩展到大型 ResultSet,因此在这种情况下,对于 500K 元素的 ResultSet 会很慢,我并不感到惊讶。有关详细信息,请参阅OrderingStrategies。
但是 TL;DR 是:您可以请求 CQEngine 使用 index 排序策略。
属性 A 的索引加速排序
在您的示例中,您需要按 (A, B) 对结果进行排序,因此您将请求 CQEngine 使用属性 A 上的索引来加速排序。由于您需要先按 A 再按 B 排序,这不会完全消除对结果进行排序的需要,因为如果引擎发现多个对象与位于索引 A 中单个存储桶中的查询匹配,它仍然必须按属性 B 显式地对该存储桶中的少量匹配对象进行排序,以实现按 (A, B) 的整体排序。
在所有其他条件相同的情况下,基于 10MM 元素的集合大小和 A 的 2MM 不同值,您可以预期 A 上索引中的每个存储桶包含 5 个对象。所以我希望这种方法可以大大减少首次结果延迟的时间。虽然它可能并不完美......
部分索引
上述方法通常适用于类似于时间序列的数据,其中 A 可能是时间戳,并且您希望搜索最近的项目并且您也希望按新近度对结果进行排序。
但是,使用属性 A 上的索引来驱动搜索与时间序列不相似的工作负载的缺点是,正在遍历 A 上的有序索引以实现结果排序,可能是 污染 有很多与您尝试加速的查询不匹配的对象。所以这会引入过滤开销。
您没有过多提及您的查询。例如,您是否提前知道查询集,或者它们完全是任意的?
我问这个问题,因为如果您事先知道您期望哪些查询(或至少您事先期望的查询的一些片段),那么您可以在属性 A 上设置 PartialIndexes 配置为em>过滤查询您希望在工作负载中找到。
部分索引(加上启用索引排序策略)可能是减轻索引污染的好方法,这意味着索引可用于加速大型 ResultSet 的排序,但它不会容易受到过度过滤的影响。希望对您有所帮助!