我有一个相当大的集合(~10 to元素),我需要运行返回相当大的结果集(~500 K元素)的查询。我需要根据两个属性对这些元素进行分组或排序:
A)有大约2MM不同的实例。B)大约有10个不同的实例。为了便于处理,所有具有匹配的(A, B)对的元素都需要组合在一起。我可能会将它们添加到映射中,然后处理映射;但是,考虑到我需要并行运行相当多的这些查询,我宁愿避免创建中间映射,而是直接从结果集中提取/处理组。
这样做的一种方法是按(A, B)进行排序;这是可行的,因为我可以从结果集中提取属于一起的块,并在进行处理时处理它们。但是,查询执行时间太慢了。我尝试向A和B添加不同类型的索引,但是似乎没有什么能提高性能。为了记录在案,我不需要对它们进行排序;我只需要匹配的(A, B)元素在结果集中一起显示。
有办法做到这一点吗?任何帮助都是非常感谢的。
发布于 2017-09-11 14:22:20
可能有几种方法来优化这一点。
在CQEngine中,我倾向于使用术语排序来描述期望的结果,然后可以使用多种排序策略来实现排序。
CQEngine中的默认行为是使用所谓的物化排序策略,这包括将匹配查询的所有结果复制到临时集合中,然后显式排序。这不能很好地扩展到大的ResultSets,所以在这种情况下,对于500 K元素的ResultSet速度慢一点也就不足为奇了。详情请参见OrderingStrategies。
然而,TL;DR是:您可以请求CQEngine使用索引排序策略。
索引-属性A的加速排序()
在您的示例中,您需要通过(A,B)对结果排序,因此您将请求CQEngine对属性A使用索引来加速排序。由于您需要按A和B进行排序,这并不能完全消除对结果排序的需要,因为如果引擎找到多个与索引A中的单个桶中的查询相匹配的对象,那么它仍然必须根据属性B显式地对该桶中的少量匹配对象进行排序,以实现(A,B)的总体排序。
在所有其他条件相同的情况下,基于10 2MM元素的集合大小和A的2mm不同值,您可以期望A上的索引中的每个桶包含5个对象。因此,我认为这种方法可以大大减少时间到第一结果的延迟。但可能并不完美..。
部分索引
上面的方法通常适用于类似于时间序列的数据,其中A可能是时间戳,而且您希望搜索最近的项,并且希望通过最近的时间来排序结果。
然而,使用属性A上的索引来驱动搜索与时间序列不同的工作负载的一个缺点是,正在遍历A上的有序索引以实现结果的排序,可能会被许多与您试图加速的查询不匹配的对象所污染。因此,这可以引入过滤开销。
你没有提到太多关于你的问题。例如,您是否预先知道一组查询,或者它们是否完全是任意的?
我会问这一点,因为如果您知道预先预期的查询(或至少预先预期的查询的一些片段),则可以在属性A上设置PartialIndexes,该属性配置了您希望在工作负载中找到的筛选器查询。
部分索引(加上启用索引排序策略)是减少索引污染的一种很好的方法,这意味着可以使用一个索引来加速大型ResultSets的排序,而且它不会受到过度过滤的影响。希望这能帮上忙!
https://stackoverflow.com/questions/46135271
复制相似问题