我正在寻找框架生成的查询的可能优化。 据我了解,该过程如下:
您可以将域对象声明为POJO并添加多个注释,例如@Entity
,@Table
,@ManyToOne
等。
您声明了您的存储库,例如每个接口
使用(2)您可以通过多种方式来描述您的查询:例如:每个方法名称或@Query
如果我写一个像:
这样的查询@Query("select t from Order t LEFT join fetch t.orderPositions where t.id = ?1")
Page<Order> findById(Pageable pageable, String id);
自动生成SQL查询,其中订单的每一列都被解析,并且顺序地用于订单定位和依赖于obejcts / tables。 好像我写道:
select * from order
因此,如果我需要来自几个连接对象的某些信息,那么查询可能会非常昂贵:而且更有趣的是非常无效。我偶然发现了一个缓慢的查询,MySQL-explain告诉我,在生成的查询中,优化器无法使用索引,这很糟糕。
当然(我知道)我必须处理权衡,生成的 SQL不如手动编写的那样最优,并且具有写入少的优势样板代码。
我的问题是:改善查询,查询执行的好策略是什么?
我自己想过一些选择:
1)是否可以为不同目的定义多个“实体”,例如Order
用于访问订单的完整特征,而FilteredOrder
更少列而不是Join-columns
的分辨率?两者都会引用相同的表,但是一个将使用所有列而另一个只使用一些。
2)使用@Query(... native="true")
选择我想要使用的所有列。这样做的好处是,我不会将我的域对象加倍,并且会使用数百个Filtered
- 对象丢弃我的代码库。
分页怎么样?将pageable
与@Query( ...native="true")
结合使用仍然可行(恐怕不行)。
3)最后但在我眼中“最差”/样板解决方案:使用JDBCTemplates
并在较低级别执行操作。
还有其他选择,我还没有想过? 感谢您对该主题的任何启发:]
更新 我们目前的策略如下
1)如果可能,我使用选择新的 正如我seen,这适用于每个对象(无论是实体还是 POJO )
2)结合数据库视图,可以充分利用 SQL 和 ORM 。对于某些用例,可能有兴趣拥有一个聚合结果集。将此结果集定义为视图使得从db-perspective可以轻松地使用简单的 select -statement来查看结果。 对于ORM方,这意味着,您可以轻松定义与此视图匹配的实体,并在顶部获得整个 ORM-goodness :分页包含
答案 0 :(得分:14)
一种解决方案是使用DTO:
@Query("select new FilteredOrder(o.name, o.size, o.cost) from Order o where o.id = ?1")
Page<FilteredOrder> findFilteredOrderById(Pageable pageable, String id);
如果您想要生成某些报告的实体,您应该考虑使用nosql数据存储区吗?
答案 1 :(得分:2)
看看JPA的懒惰抓取策略。它允许您选择没有关系的对象,但会在您引用它们时获取关系。