使用动态查找器进行并行查询的Grails设计模式

时间:2015-04-29 13:13:04

标签: grails design-patterns parallel-processing dynamic-finders

问题: 我们用很多条目查询我们的数据库。整体应用程序性能还可以。但我认为,如果我们的瓶颈,查询特殊表格可以并行完成,那可能会更好。

我们正在使用像以下那样的动态查找器:

Object.findAllByObjectCollectionAndParentIsNullAndDeletedByUserIsNull(objectCollection, [sort: 'attr1.number', fetch: [objectType: 'eager']])

我考虑这个解决方案:将查询分为两个步骤。

  1. 第一步仅以有序方式加载ID。
  2. 第二步(可以在并行线程中完成)通过id加载对象本身并将其插入到结果集中。
  3. 我已经用谷歌搜索了一些提示,但什么也没找到。

    1. 是否有可能,这没有意义?
    2. 或者Grails标准/扩展中是否已有足够的解决方案?
    3. 如果它有意义并且没有解决方案:有人可以给我一个提示吗?但是,我们需要以有序的方式使用ID,在示例中进行了解释。
    4. 我们正在使用grails 2.3.11,hibernate:3.6.10.13,其下有jdk 1.7。

1 个答案:

答案 0 :(得分:0)

我找到了解决方案!

ArrayList<Long> objectIds = Attribute.executeQuery("select o.id from Object o, ObjectType ot where o.objectCollection = :oc and o.parent is null and o.deletedByUser is null and oc.typeUsage = ot order by ot.nr asc", [oc: objectCollection])
Object[] tmp = new Object[objectIds.size()]
        withPool(10, {
            objectIds.eachWithIndexParallel {
                Long objectId, i ->
                    Object o = Object.findById(objectId, [cache: true])
                    tmp[i] = a
            }
        })
        for (Object a : tmp)
            a.merge()

它的回合慢了约3倍!

我认为原因是,

  1. 我们也必须创建线程和数据库连接。
  2. 加载对象后,需要将它们合并到我们的本地线程中。
  3. 但最终 - 我们无法使用它,因为延迟加载的字段无法在以后按需加载。所以这可能只是一个只读对象的解决方案