0

問題: 多数のエントリでデータベースをクエリしています。全体的なアプリケーションのパフォーマンスは問題ありません。しかし、ボトルネックである特別なテーブルへのクエリを並行して実行できれば、より良いと思います。

そのために、次のような動的ファインダーを使用しています。

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

この解決策について考えます。クエリを2つのステップに分割します。

  1. 最初のステップでは、ソートされた方法で Id のみをロードします。
  2. 2 番目のステップ (並列スレッドで行うことができます) では、id によってオブジェクト自体をロードし、それを結果セットに挿入します。

私はすでにそれについていくつかのヒントを探しましたが、何も見つかりませんでした。

  1. それが意味をなさない可能性はありますか?
  2. または、grails の標準/拡張機能に適切なソリューションが既にありますか?
  3. それが理にかなっており、解決策がない場合: 誰かがそれを実装するためのヒントを教えてくれますか? ただし、例で説明されているように、並べ替えられた方法で ID が必要です。

grails 2.3.11、hibernate:3.6.10.13 を jdk 1.7 の下に使用しています。

4

1 に答える 1

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. オブジェクトをロードしたら、それらをローカル スレッドにマージする必要があります。

しかし、結局のところ、遅延ロードされたフィールドは後でオンデマンドでロードできなかったため、使用できません。したがって、これは読み取り専用オブジェクトのソリューションにすぎない可能性があります

于 2015-04-30T09:04:06.083 に答える