优化Spring-Data JPA查询

我正在寻找框架生成的查询的可能优化。 据我了解,该过程如下:

  • 你可以将你的域对象声明为POJO并添加几个注释,如@ManyToOne@ManyToOne@ManyToOne等。

  • 你声明你的存储库,例如每个接口

使用(2),您可以使用多种方法来描述查询:例如,根据Methodnames或@Query

如果我写一个像这样的查询:

 @Query("select t from Order t LEFT join fetch t.orderPositions where t.id = ?1") Page findById(Pageable pageable, String id); 

自动生成SQL查询,其中订单的每一列都被解析,并且顺序地用于订单定位和依赖于obejcts / tables。 好像我写道:

 select * from order 

因此,如果我需要来自几个连接对象的一些信息,那么查询可能会非常昂贵:而且更有趣的是非常无效。 我偶然发现了一个缓慢的查询,MySQL-explain告诉我,在生成的查询中,优化器无法使用索引,这很糟糕。

当然(我知道)我必须处理权衡, 生成的 SQL不像手动编写那样最优,并且具有编写较少样板代码的优势。

我的问题是:改善查询,查询执行的好策略是什么?

我自己想过一些选择:

1)是否可以为不同的目的定义几个“实体”,例如Order访问Order完整特征,以​​及类似FilteredOrder的列数较少但没有Join-columns分辨率? 两者都会引用相同的表,但是一个将使用所有列而另一个只使用一些。

2)使用@Query(... native="true")选择我想要使用的所有列。 这样做的好处是,我不会将我的域对象加倍,并且会使用数百个Filtered -Objects丢弃我的代码库。 分页怎么样? 将@Query( ...native="true")@Query( ...native="true")结合使用仍然是可能的(恐怕不行)。

3)最后但在我眼中“最差”/样板解决方案:使用JDBCTemplates并在较低级别执行操作。

还有其他选择,我还没想过? 感谢您对该主题的任何启发:]

更新:我们目前的战略如下

1)在可能的情况下,我使用select new正如我所见 ,这适用于每个对象(无论是实体还是POJO

2)结合数据库视图 ,可以充分利用SQLORM 。 对于某些用例,可能有兴趣拥有一个聚合结果集。 将此结果集定义为视图使得从db-perspective可以轻松地使用简单的select -statement来查看结果。 对于ORM方面,这意味着,您可以轻松定义与此视图匹配的实体,并在顶部获得整个ORM优点 :分页包含。

一种解决方案是使用DTO:

 @Query("select new FilteredOrder(o.name, o.size, o.cost) from Order o where o.id = ?1") Page findFilteredOrderById(Pageable pageable, String id); 

如果您想要生成某些报告的实体,您应该考虑使用nosql数据存储区吗?

看看JPA的懒惰抓取策略。 它允许您在没有关系的情况下选择对象,但在引用它们时将获取关系。