我在DB中有以下表格:
Person
,
Parent
,
GrandParent
Parent - Person
为OneToMany
关系(Person
有parentId
)
GrandParent - Parent
是ManyToMany
关系(grandparent_parent
表)
我在PersonRepository
中创建了JPARepository
:
@Query("SELECT person.uuid FROM Person person JOIN person.parent parent JOIN parent.grandparents grandparent WHERE grandparent.uuid = ?1")
Set<String> findByGrandParentId(final String parentId);
用于获取Person
以下GrandParent
的所有ID。
创建此SQL:
SELECT
person0_.uuid as col_0_0_
FROM
person person0_
INNER JOIN
parent parent1_
on person0_.parentid=parent1_.uuid
INNER JOIN
grandparent_parent grandaparent_parent2_
on parent1_.uuid=grandaparent_parent2_.parentid
INNER JOIN
grandparent parent3_
on grandaparent_parent2_.grandparentid=parent3_.uuid
WHERE
parent3_.uuid='13906f55-441c-45bd-bef6-8beefa4119c4'
我记录了存储库需要获取数据的时间,并且(平均) ~400ms 来获取 ~400 记录。 然后我在DB上执行相同的SQL查询,每次查询不超过 50ms 。
我知道这个生成的查询没有优化,因为我们只能加入两个表GRANDPARENT_PARENT
和PERSON
,但这不是问题,因为这样的查询也在 50ms以下执行
为什么我在使用存储库获取和在db中获取之间存在这样的差异?有可能解决这个问题吗?
答案 0 :(得分:2)
多种可能性:
<强> 1。生成的查询
生成的查询对我来说非常好。它与@Query
注释中的查询完全相同。
<强> 2。 SQL结果转换为Java对象
我不知道你的表有多大,但是:将SQL结果转换为Java对象需要一些时间。对于小型表,这可以将查询时间增加0-5%。
第3。延迟加载
您没有显示实体的代码。如果您有@OneToMany
或@ManyToMany
关系,JPA将默认使用延迟加载。这实际上可以通过幅度减慢一切。
<强> 4。延迟强>
如果您在SQL DB所在的同一台机器上执行SQL查询,但您的Java应用程序通过网络与SQL DB进行通信,则也会导致查询速度变慢。
(5.错误的DB。似乎你构建了一个对象图。也许看看Neo4j ;-)
)