当前位置: 首页 > 知识库问答 >
问题:

Spring Data JPA QueryDSL查询优化

姬捷
2023-03-14

我在使用与Spring Data JPA集成的QueryDSL时遇到了一个奇怪的行为:

我在Project和Person之间有ManyToOne关系。如果我通过所有者ID(外键)获取属于用户的所有项目,一切都按预期工作:

QProject project = QProject.project;
QPerson owner = project.owner;
List<Project> projects = from(project).leftJoin(owner).fetch()
    .where(owner.id.eq(id)).list(project);

生成的查询:

select
    project0_.id as id1_1_0_,
    person1_.id as id1_0_1_,
    project0_.creation_date as creation2_1_0_,
    project0_.name as name3_1_0_,
    project0_.owner as owner4_1_0_,
    person1_.name as name2_0_1_
from
    project project0_
left outer join
    person person1_
        on project0_.owner=person1_.id
where
    project0_.owner=?

但是,假设我们想通过一个不是外键的字段(例如所有者的姓名)获取属于一个人的所有项目:

QProject project = QProject.project;
QPerson owner = project.owner; 
List<Project> projects = from(project).leftJoin(owner).fetch()
    .where(owner.name.eq(name)).list(project);

在这些情况下,表Person被不必要地连接了两次(请注意person1_和person2_):

select
    project0_.id as id1_1_0_,
    person1_.id as id1_0_1_,
    project0_.creation_date as creation2_1_0_,
    project0_.name as name3_1_0_,
    project0_.owner as owner4_1_0_,
    person1_.name as name2_0_1_
from
    project project0_
left outer join
    person person1_
        on project0_.owner=person1_.id cross
join
    person person2_
where
    project0_.owner=person2_.id
    and person2_.name=?

任何想法为什么会发生这种情况以及如何避免它?

共有1个答案

廖鸿达
2023-03-14

您需要创建一个别名,以确保在where-part中重用第一个联接

QProject project = QProject.project;
QPerson owner = new QPerson("owner");
List<Project> projects = from(project)
    .leftJoin(project.owner, owner).fetch()
    .where(owner.name.eq(name))
    .list(project);
 类似资料:
  • 问题内容: 这就是整个查询… 如果… 和… 有明显的理由吗? 正在服用? 扩展说明 问题答案: 您可以始终使用EXPLAIN或EXPLAIN EXTENDED 来查看MySql对查询所做的操作 您也可以用稍微不同的方式编写查询,是否尝试过以下方法? 看看效果如何会很有趣。我希望它会更快,因为目前,我认为MySql将为您拥有的每个节目运行内部查询1(这样一个查询将运行多次。联接应该更有效。) 如果希

  • 问题内容: 我希望从我的用户模型中检索一些信息,如下所示: 在主页中,我有一个 位置 过滤器,您可以在其中浏览来自国家或城市的用户。 所有字段还包含其中的用户数: 在主页上,然后我还有“学生和老师”页面,我希望仅提供有关这些国家和城市有多少老师的信息… 我想做的是创建一个对MongoDB的查询,以通过单个查询检索所有这些信息。 此刻查询如下: 问题是我不知道如何获取所需的所有信息。 我不知道如何获

  • 问题内容: 此查询需要153秒才能运行。中有数百万行。 我认为查询要花很长时间,因为where子句中的功能。但是,我需要在列上执行ltrim rtrim,而且日期也必须在格式上匹配。如何优化此查询? 说明计划: 首要的关键: 索引: 但是,在解释计划中,我看不到使用索引/主键。那是问题吗? 问题答案: 试试这个: 如果尚无时间,请从其外观(出生日期?)上删除该对象。除此之外,您还需要一些索引工作。

  • 主要内容:概述,一、关联查询优化,1.左(右)外连接,2.内连接,3.JOIN语句原理,4.JOIN小结,5.Hash Join,二、子查询优化,三、排序优化,四、GROUP BY优化,五、优先考虑覆盖索引,六、使用前缀索引,七、索引下推ICP,八、其他查询优化,1.COUNT(*)与COUNT(具体字段)效率,2.不使用SELECT *,3.LIMIT 1优化,4.多使用commit概述 数据库调优的方式有多种: 建立索引、充分利用到索引、不让索引失效 对SQL语句进行优化 调优如缓冲、线程数

  • 问题内容: 我正在寻找框架生成的查询的可能的优化。据我了解,该过程如下: 你可以声明你的域对象是POJO和增加几个注解像,,等等。 您声明您的存储库,例如每个接口 使用(2),您可以通过多种方式描述您的查询:例如,每个方法名或 如果我写这样的查询: 将自动生成一个SQL查询,其中解析订单的每一列,并随后解析订单位置和相关对象/表。好像我写了: 因此,以防万一,我需要来自 多个 连接对象的 一些 信

  • 问题内容: 一个供您所有MySQL专家使用的技巧:-) 我有以下查询: 订单表= 80,900行 产品表= 125,389行 o.id和p.order_id已建立索引 该查询大约需要6秒钟才能完成-太长了。我正在寻找一种优化它的方法,可能使用临时表或其他类型的联接。恐怕我对这两个概念的理解还很有限。 谁能建议我优化此查询的方法? 问题答案: 首先,我将使用其他样式的语法。 已经有20年的睡眠时间了

  • 问题内容: 我不太擅长SQL,因此我要求你们提供有关编写查询的帮助。 [SQL查询-表连接问题]https://codingdict.com/questions/208252) 我得到了答案,并且可以正常工作!它只是明显的缓慢。我讨厌这样做,但是我真的希望有人在那里推荐一些优化查询的方法。我什至没有自己尝试过,因为我对SQL不够了解,甚至无法开始使用谷歌搜索。 问题答案: 可能有帮助的是在要加入的

  • 我正在为框架生成的查询寻找可能的优化。据我所知,过程如下: > 您可以将域对象声明为POJO并添加几个注释,例如、、等。 您声明您的存储库,例如每个接口 使用(2),您有几个选项来描述您的查询:例如,每个方法名或 如果我写一个类似如下的查询: SQL查询是自动生成的,其中订单的每一列都会被解析,然后依次针对订单位置和依赖对象/表。就像我写道: 因此,如果我需要来自多个联接对象的一些信息,查询可能非