문제

Hibernate의 JPA 구현을 사용하고 있으며 각 엔티티에 대해 여러 SQL 쿼리가 발행되므로 성능 저하가 열악하고 있습니다. 결합 된 JPA 쿼리를 사용하면 하나의 SQL 쿼리 만 생성하지만 행을 찾지 못하면 관계가 없습니다.

예를 들어이 간단한 스키마를 고려하십시오. 사람은 주소에 거주하며 회사가 고용합니다. 주소와 고용주는 모두 선택 사항이므로 NULL이 될 수 있습니다.

@Entity
public  class Person {
    public name;

    @ManyToOne
    @Column(nullable=true)
    public Address address

    @ManyToOne
    @Column(nullable=true)
    public Company employer
}

@Entity
public  class Address {
    address attributes ...
}

@Entity
public  class Company {
    company attributes ...
}

위에는 표시되지 않음 각 JPA 엔티티에는 일종의 ID (키)가 있다는 것입니다.

@Id
public Integer id;

내가보고있는 문제는 사람의 단일 JPA 쿼리가 데이터베이스에서 여러 SQL 쿼리를 초래한다는 것입니다. 예를 들어 다음 JPA 쿼리 :

select p from Person p where ...

SQL 쿼리의 결과 :

select ... from Person where ...

또한 다음과 같은 SQL 쿼리 쌍입니다 검색된 사람 :

select ... from Address a where a.id=xxx
select ... from Company c where c.id=yyy

이것은 성능에 큰 영향을 미칩니다. 쿼리 결과 세트가 1000 명인 경우 1+1000+1000 = 2001 SQL 쿼리를 생성합니다.

그래서 JPA 쿼리를 가입하도록하여 JPA 쿼리를 최적화하려고 시도했습니다.

select p from Person p join p.address a join p.employer e where ...

또는:

select p, a, e from Person p join p.address a join p.employer e where ...

이로 인해 많은 결합이있는 단일 SQL 쿼리가 발생합니다. 문제는 주소 또는 고용주가 null이면 결합 된 쿼리가 찾을 수 없다는 것입니다.

따라서 느린 조인 쿼리를 사용하거나 행을 검색하지 않는 빠른 결합 쿼리가 관계가 무효화됩니다. 나는 여기서 뭔가를 놓치고 있어야한다. 확실히 빠르고 완전한 쿼리를위한 방법이 있습니다.

도움이 되었습니까?

해결책

내 생각에 왼쪽 가입이 필요하다는 것입니다.

SELECT p FROM Person p LEFT JOIN p.address a LEFT JOIN p.employer e WHERE...

보다 이 블로그 항목은 예를 들어 있습니다

실제로 JPA에서 이것을 시도하지는 않았지만 HQL에서는 잘 작동합니다. 이는 여러면에서 JPA 표준의 기초입니다.

Plain Join 's와 함께 작동하지 않는 이유는 기본값이 내부 결합이기 때문입니다.

다른 팁

주소 및 회사 엔티티에서 배치 크기 (@batchsize)를 설정해보십시오. 그것은 결합에로드하지 않을 것입니다 (당신이 따르는 것입니까?). 그러나 하나가로드 될 때마다 많은 양을로드 할 것입니다. 배치 크기는 그것이 필요하다는 것을 발견 할 때 얼마나 많은 것을로드 해야하는지 말합니다.

배치 크기가 1 (기본값)이고 10 명을로드하십시오. 그런 다음 주소와 회사 항목을 읽은 다음 최대 절전 모드는 10 명을 위해 하나의 쿼리를 수행 한 다음 해당 사람들 중 하나를 위해 주소 또는 회사가 필요할 때마다 해당 사람의 주소를 쿼리 할 것입니다.

주소 엔티티에서 7의 배치 크기를 설정 한 경우 첫 번째 주소를 읽으면 현재 프록시 된 7 개 이상의 주소가 있으며 주소 7 개 이상을 얻을 수 있습니다.

배치 크기가 7 인 주소와 회사를 모두 가지고 있고 10 명을 반복한다면, 이로 인해 21 yo가 아닌 5 개의 쿼리가 발생합니다. 여전히 1은 당신에게 wold가주는 1이 아닙니다. 그러나, 당신이 사람의 물체를 원하고 주소/회사 엔티티에 내장 된 주소/회사 엔티티를 만지지 않을 경우에 조인은 느려질 것입니다 (개인 ID 목록을 얻거나 얼마나 많은지 계산하고 싶다고 말합니다. 남성/여성)

다음을 살펴보십시오.http://hibernate.org/hib_docs/v3/reference/en/html/performance.html

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top