CQEngine +大结果集:按多个属性排序或分组性能

时间:2017-09-09 21:28:52

标签: cqengine

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

  1. 第一个属性(让我们称之为A)有大约2MM个不同的实例。
  2. 第二个属性(让我们称之为B)有大约10个不同的实例。
  3. 需要将具有匹配(A, B)对的所有元素组合在一起以进行处理。我可能会将它们添加到地图中然后处理地图;但是,鉴于我需要并行运行相当多的查询,我宁愿避免创建中间映射,而是直接从结果集中提取/处理组。

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

    有没有办法实现这个目标?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

可能有几种方法可以优化它。

在CQEngine中,我倾向于使用术语排序来描述所需的结果,然后可以有多种排序策略来实现排序。

CQEngine中的默认行为是使用所谓的 materialize 排序策略,该策略涉及将与查询匹配的所有结果复制到临时集合中,然后将其显式排序。这不适用于大型ResultSet,因此在这种情况下,对于500K元素的ResultSet来说,这并不奇怪。有关详细信息,请参阅OrderingStrategies

然而TL; DR是:您可以请求CQEngine使用索引排序策略。

属性A的索引加速排序

在您的示例中,您需要按(A,B)排序结果,因此您可以请求CQEngine使用属性A上的索引来加速排序。由于您需要按A然后按B进行排序,这不会完全消除排序结果的需要,因为如果引擎找到多个与索引A中单个存储桶中共存的查询匹配的对象,它仍然必须按属性B对该桶中的少量匹配对象进行显式排序,以便通过(A,B)实现整体排序。

所有其他条件相同,基于10MM元素的集合大小和A的2MM不同值,您可以预期A上的索引中的每个桶包含5个对象。所以我希望这种方法可以大大缩短首次结果延迟时间。虽然可能不完美......

部分索引

上述方法通常适用于类似于时间序列的数据,其中A可能是时间戳,并且您希望搜索最近的项目,并且您希望按新近度订购结果。

然而,使用属性A上的索引来驱动搜索与时间序列不相似的工作负载的缺点是,正在遍历以实现结果排序的A上的有序索引可能是污染,其中包含许多与您尝试加速的查询不匹配的对象。所以这可以引入过滤开销

您没有多提及您的疑问。例如,您是否提前知道了一组查询,还是完全是任意的?

我问这个问题,因为如果你事先知道了你期望的查询(或者至少是你提前预期的一些查询片段),那么你可以在属性A上设置PartialIndex es您希望在工作负载中找到过滤器查询

部分索引(加上启用索引排序策略)可以是缓解索引污染的好方法,这意味着索引可用于加速大型ResultSet的排序,而且不会容易过度过滤。希望有所帮助!