1

私は基本的に、JPQL クエリを実行することにより、datanucleus を介して適切なサイズの結果セット (数千) を取得しています。これらのそれぞれについて、別のテーブルからの参照の数も調べたいと思います。データは MySQL データベースにあります。

例えば:

List<Instrument> instruments = em().createQuery("SELECT i FROM Instrument AS i").getResultList();
for(Instrument i : instruments)
{
    Query q = em().createQuery("SELECT COUNT(c) FROM Component AS c WHERE c.instrument.id = :id")
    q.setParameter("id", i.getId());
    long count = (Long) q.getSingleResult();
}

したがって、基本的には、上記の例のように、楽器のリストと、楽器に取り付けられたコンポーネントのリストが必要です。

私は多くの場所で同様のコードを使用しましたが、パフォーマンスはかなり悪いです。2000 個のインストゥルメントの場合、コンポーネントをカウントするために 2000 個のクエリを追加で実行すると、速度が低下することを理解しています。私が望むのと同じ結果を得るためのより良いパターンがあると確信しています。どうすれば高速化できますか?

4

1 に答える 1

1

そうです、これは最適なソリューションではありません。しかし、良いニュースは、これらすべてが1つまたは多くても2つのクエリで実行できることです。たとえば、ごとに1回カウントクエリを実行する必要はありませんinstrument。グループ化を使用して、1つのクエリですべてのカウントを取得できます。

List<Instrument> instruments = em().createQuery("SELECT i FROM Instrument AS i").getResultList();

Query q = em().createQuery("SELECT c.instrument.id, COUNT(c) FROM Component AS c GROUP BY c.instrument.id")
List<Object[]> counts = q.getResultList();

for (Object[] elem : counts) {
    // do something 
    // elem[0] is instrument ID
    // elem[1] is count
}

私はそれを確認していませんが、2番目のクエリを最初のクエリのサブクエリとして配置することで、1つのクエリですべてを実行することもできます。

SELECT i 
(SELECT COUNT(c) FROM Component AS c WHERE c.instrument.id = i.id)
FROM Instrument AS i

最初の例と同様に、結果リストelem[0]はanInstrumentおよびelem[1]カウントになります。DBはとにかく各機器のサブクエリを実行する必要があるため、効率が低下する可能性がありますが、完全にDB側で行われるため、コードよりも高速になります(カウントクエリごとにDBへのラウンドトリップはありません)。

于 2012-10-25T09:45:00.043 に答える