1

次の問題を想像してみてください。誰かが、アフリカと南アメリカからの緑の果物が入った果物のバスケットを購入したいと考えていますが、アフリカからの赤い果物はありません。

そのために、次のクラスについて考えます。



    class Basket
    {
      int id;
      Collection<Fruit> fruits; 
    }

    class Fruit
    {
      int id;
      int basketId;
      String origin
      Color color;
    }

マッピングは MxM になります。Fruit には Basket オブジェクトがないことを意図していますが、必要に応じて実装できます。

ネイティブ SQL の場合、次を使用します。



    SELECT * 
    FROM 
      Basket b 
    JOIN 
    (
      SELECT DISTINCT basketId 
      FROM Fruit 
      WHERE color='green' AND (origin='Africa' OR origin='South America')
    ) f1 ON (b.id=f1.basketId) 
    LEFT JOIN 
    (
      SELECT DISTINCT basketId 
      FROM Fruit 
      WHERE color='red' AND (origin='Africa')
    ) f2 ON (b.id=f2.basketId) 
    WHERE f2.basketId IS NULL 

JPQLのクエリはどうなりますか?

私はすでに以下を試しました:



    SELECT b 
    FROM Basket b 
    WHERE 
      b.id IN (
        SELECT f1.basketId FROM Fruit f1 
        WHERE f1.color='green' AND (f1.origin='Africa' OR f1.origin='South America')
      ) AND
      b.id NOT IN (
        SELECT f2.basketId FROM Fruit f2 
        WHERE f2.color='red' AND (origin='Africa'))

しかし、このクエリには 50 ミリ秒ではなく 12000 ミリ秒かかりました。(これは単純な例です。実際のテーブルには、約 750000 個の「果物」と 10000 個の「バスケット」があり、それぞれより多くのフィールドがあります。)

前もって感謝します

ジェラルド

4

2 に答える 2

0

あなたは試すことができます

select b from Basket b where
    exists (select f.id from Fruit f where f.basket = b and f.color = 'green')
    and not exists (select f.id from Fruit f where f.basket = b and f.color = 'red')

しかし、もっと速くなるかどうかはわかりません。これは、データベースインデックスに依存する実行プランに依存します。Fruit.basketIdにインデックスが必要Fruit.colorです。

于 2011-09-15T16:28:19.360 に答える
0

これは機能しますか?

select b from Basket b join b.fruits f where f.color = 'green' and not f.color = 'red';

結合はおそらくオプションなので、そうすることもできます

select b from Basket b where b.fruits.color = 'green' and not b.fruits.color = 'red';
于 2011-09-15T17:27:46.050 に答える