【问题标题】:Need to convert an LEFT JOIN to JPQL需要将 LEFT JOIN 转换为 JPQL
【发布时间】:2011-09-15 16:02:30
【问题描述】:

想象以下问题: 有人想买一篮子水果,里面有非洲和南美洲的绿色水果,但没有非洲的红色水果。

为此,我们考虑以下类:



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

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

映射将是 MxM。 Fruit 没有 Basket 对象,但如有必要,我可以实现它。

对于 Native 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'))

但是这个查询需要 12000 毫秒而不是 50 毫秒。 (这只是一个简单的例子。真正的表格有大约 750000 个“水果”和 10000 个“篮子”,每个都有更多的字段。)

提前致谢

杰拉德

【问题讨论】:

  • 到目前为止我发现了什么:基准平均查询时间(10000 次查询):a)标准 SQL(左连接)vs b)JPQL(存在):MySQL:a=60s vs b=1050s; PostgreSQL:a=144s vs b=62s; H2:a=77s vs b=1817s

标签: jpa left-join jpql outer-join migrate


【解决方案1】:

你可以试试

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 上应该有一个索引。

【讨论】:

  • 子选择已经从之前的查询中很好地索引了。我将索引添加到“basketId”,但它仍然需要很长时间...... :-/ 我认为 EXISTS 的工作方式类似于 IN。
【解决方案2】:

这行得通吗?

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';

【讨论】:

  • hmmm 我想我需要扩展这个例子......关于水果类中有一个额外的字段“字符串来源”,你想要来自非洲和南美洲的绿色水果,而不是来自非洲和南美洲的红色水果非洲。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 2012-02-04
  • 2015-05-19
  • 2020-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多