【问题标题】:CQEngine + large result set: sort or group by multiple attributes performanceCQEngine + 大结果集:按多属性排序或分组性能
【发布时间】:2017-09-09 21:28:51
【问题描述】:

我有一个相当大的集合(~10MM 元素),我需要运行返回相当大的结果集(~500K 元素)的查询。我需要那些按两个属性分组或排序的元素:

  1. 第一个属性(我们称之为A)有大约 2MM 个不同的实例。
  2. 第二个属性(我们称之为B)有大约10个不同的实例。

所有具有匹配(A, B) 对的元素都需要组合在一起以进行处理。我可以,潜在地,将它们添加到地图中,然后处理地图;但是,考虑到我需要并行运行很多这样的查询,我宁愿避免创建中间映射,而是直接从结果集中提取/处理组。

一种方法是按(A, B) 排序;这行得通,因为我可以从结果集中提取属于一起的块并随时处理它们。但是,查询执行时间太慢了。我尝试向A 和B 添加不同类型的索引,但似乎对性能没有任何帮助。作为记录,我不需要对它们进行排序;我只需要匹配的(A, B) 元素一起显示在结果集中。

有没有办法做到这一点?任何帮助表示赞赏。

【问题讨论】:

    标签: cqengine


    【解决方案1】:

    可能有几种方法可以对此进行优化。

    在 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 的排序,但它不会容易受到过度过滤的影响。希望对您有所帮助!

    【讨论】:

    • 感谢您的回复 - 我尝试了这两个建议,但 CQ 似乎只是忽略了索引并进行后排序。我尝试使用 INDEX_ORDERING_SELECTIVITY,但是当我指定该选项时,排序停止工作。
    • 更详细地说,A 和 B 都是字符串,它们不是 where 子句的一部分。我事先不知道查询集,这是针对共享缓存服务的,不知道人们将如何查询它。我还尝试在A 和B 上创建一个复合属性,只需将它们连接起来,然后在其上创建一个NavigableIndex,但这似乎也没有效果-它仍然进行后排序。
    • 我确实可以控制我上面提到的“用例”查询。
    • 为了让引擎利用索引进行排序,需要满足许多要求。然而,有一种方法可以让它记录它的决定,这可能会告诉我们发生了什么:github.com/npgall/cqengine/blob/2.12.1/code/src/main/java/com/…
    • 我猜堆栈溢出并不是详细调试这个特定问题的最佳媒介。该项目有一个讨论论坛。如果您想在那里发布问题的详细信息,我可以帮助您启用调试日志记录以查看发生了什么。 groups.google.com/forum/#!forum/cqengine-discuss
    猜你喜欢
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    相关资源
    最近更新 更多