0

问题: 我们用很多条目查询数据库。整体应用程序性能还可以。但我认为,如果我们的瓶颈,查询一个特殊的桌子,可以做得更好。使用动态查找器进行并行查询的Grails设计模式

我们正在使用该动态查找,如:

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

我认为这个解决方案:将查询到2个步骤。

  1. 第一步只以有序方式加载Ids。
  2. 第二步(可以在并行线程中完成)通过id加载对象本身并将其插入到结果集中。

我已经在Google上搜索了一些关于这方面的提示,但什么都没发现。

  1. 是否有可能,这是没有意义的?
  2. 或者在grails标准/扩展中是否已经有适当的解决方案?
  3. 如果它是有道理的,并没有解决方案:有人可以给我一个提示实施它吗?但是,我们需要按照这种排序的方式进行编码,在示例中进行了解释。

我们使用的是grails 2.3.11,hibernate:3.6.10.13,下面有jdk 1.7。

+1

你记录了你的findAll查询的SQL,试图分析它的功能吗?父母是否有索引并被删除?否则只有一种方法可以找出这样的事情:试用它并进行基准测试。当谈到表演的时候,那里的所有案件往往没有银弹。 – cfrick

+0

当然可以。我们正在加载的这些对象持有非常小的数据元素,就像Excel工作表单元格一样。所以当页面呈现时,我们需要很多。 – Mirko

回答

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. 我们要创建线程,databaseconnections了。
  2. 加载对象后,需要将它们合并到本地线程中。

但最后 - 我们无法使用它,因为懒惰的加载字段不能在以后按需加载。因此,这可能只是一个解决方案,只读对象