数据库函数返回特定半径内所有事件的id,按其距离排序。
之后,为了保持性能,我急切地在echo "leonardo,davinci" | pcregrep '[^\w\s,]'
加载必要的集合,如下所示:
withCriteria
然而,这会扰乱排序。我注意到这个条件查询的结果返回按id排序的所有事件。这有点有意义,因为 def events = Event.withCriteria {
'in'('id', ids)
fetchMode("someRelation", FetchMode.JOIN)
// a few more joins
setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
}
不保证任何类型的特殊排序(它也没有任何意义)。然而,这会带来一些问题,因为我希望这个列表是有序的。
所以我做的是:
in
然而,当列表包含~2400个元素时,这段代码会增加大约1秒的总执行时间,这是我希望尽可能降低的。
还有其他方法可以加快这个过程吗?
答案 0 :(得分:1)
我认为至少有三种方法可以解决您的问题(我已经做了额外的研究和考虑):
根据this gist,按字段排序也可以使用Postgres而不仅仅是在mysql中,但它有点棘手,因为它不是直接支持的。正如您在gist讨论中所读到的那样,有不同的方法,但我认为更简洁的是最后一种:通过子句添加自定义订单!
ORDER BY (ID=10, ID=2, ID=56, ID=40) DESC
要在Grails中创建返回具有特定类型的对象的自定义SQL查询,您可以关注this tutorial
// only four id, for the sake of simplicity
def ids = [10, 2, 56, 40];
// get your events with your criteria
def events = Event.withCriteria {
'in'('id', ids)
fetchMode("someRelation", FetchMode.JOIN)
// a few more joins
setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
}
// create an array that maps event.id -> sortedEventIndex
def indexToIdArray = [];
// event with id 2 is at index 1
// event with id 10 is at index 0
// ...
// [null, null, 1 , null, null, null, null, null, null, null, 0, ...]
ids.eachWithIndex{ num, idx -> indexToIdArray[$num] = $idx }
def sortedEvents = [];
events.each { ev -> sortedEvents[indexToIdArray[ev.id]] = ev }
通过这种方式,您已经在 O (n)中进行了排序,消耗了一些额外的内存。 我不知道这个解决方案是否真的比你的更好,但是你应该试一试。
另请参阅this interesting article,了解如何在groovy代码中找到性能问题。
使用排序数据将未排序的事件列表返回给客户端,然后在客户端中对它们进行排序。如果您的应用程序的客户端可以以更多方式对事件列表进行排序,我认为此解决方案可能很有用(每个排序操作仅在客户端完成)。
由于这也是一个性能问题,还有其他可能的解决方案(取决于您的域/环境):
我希望这会有所帮助。