나는 오랜 시간이 걸리는 쿼리를 가지고 있으며이를 최적화하려고합니다. 나는 그것을하는 가장 효율적인 방법을 찾고 있습니다.쿼리 최적화 - 필드 또는 다른 테이블 사용
나는 PostgreSQL DB가있는 Hibernate/JPA에서 일하고 있지만 모든 솔루션은 일반적인 JPA 중 하나 여야합니다.
용어
- 사용자 : 시스템의 사용자입니다.
- 친구 : 사용자의 친구. 사용자에게는 N 명의 친구가 있습니다.
- 세션 : 시스템 사용 세션. 열거 나 닫을 수 있습니다.
- 컨텍스트 : 세션 컨텍스트. 사용자는 주어진 시간에 컨텍스트 당 하나의 열린 세션을 가질 수 있으며 컨텍스트 당 많은 과거의 닫힌 세션을 가질 수 있습니다.
쿼리 나 사용자 이름 주어진 다음 나에게주는 쿼리 구현해야
:
- 해당 사용자 각각에 대해
- 모든 친구를 가져 오기를 친구 :
- 친구가 열려있는 세션이있는 경우 모든 컨텍스트에 대해 열려있는 모든 세션을 가져옵니다.
- 그렇지 않으면 모든 컨텍스트에서 친구의 최신 세션을 가져옵니다. 우정 그래서 난 어떤 경우에 하나 개의 큰 쿼리로 그것을 포함하지 수있는 다른 DB에 저장되어 는
참고. B, C, D :
예
사용자 A가 세 친구가 있습니다. 1과 2의 두 가지 상황이 있습니다.친구는 다음과 같은 데이터를 가지고 :
(아래 서식은 세션 ID입니다 - 사용자, 컨텍스트)
- 1 - B, 1 : 오픈 세션
- 2 - B, 2 : 시작 비공개 회의 2 월 27 일에
- 3 - B, 2 : 시작 폐쇄 세션 2 월 26
- 4 - C : 1, 2 월 27
- 5 시작 폐쇄 세션 - C : 1 폐쇄 세션 그 2 월 26 일에 시작했습니다.
- 6 - C, 2 : 2 월 26
- 7 시작 폐쇄 세션 - C, 2 : 폐쇄 세션 2 월 25
- 8 시작 - D, 1 개 세션
- - 9 D, 2 : 오픈 세션
쿼리는 저를 얻어야한다 : B : 세션 1 (열려있는 모든 세션) C : 세션 4 (최신 비공개 회의) D : 세션 8,9 (열려있는 모든 세션)
현재 상태
내 쿼리는 세 단계로 작동합니다있을 경우
- 이 친구
- 을 열려있는 모든 세션을 가져 오기 :
- 각 친구를 위해 사용자
- 의 모든 친구를 가져옵니다 열려있는 모든 세션은,
- 이 친구의 최신 세션을 가져 열려있는 모든 세션을 반환 세션을 반환
분명히 이것은 많은 쿼리입니다. 처음에는 위의 2 단계를 수행하여 단일 쿼리으로 변환하겠습니다. 내 우려는 두 번째 쿼리와 관련이 있습니다. 문제는 그것이 더 최적화되도록하는 방법입니다. 문제는, 따라서 고쳐 할 수 있습니다
이"N 친구 ID의 집합을 감안할 때, 열려있는 모든 세션이나 모든 친구를위한 최신 세션을 얻을."
제안 된 솔루션을
우리가 함께했다 기본적으로 두 가지 해결책이 있고 우리는 더 나은 것 무엇을 고민하고 있습니다.
테이블 솔루션은 사용자, 컨텍스트 및 최신 세션간에 상관 관계가있는 새 테이블을 유지한다고 말합니다.이 솔루션의 의미는 다음과 같습니다
- 사용자
- 상황
- 최신 세션 ID :
- 이 표는 이러한 열을 것 "최신 세션"
- 의 새로운 법인 & 테이블을 만듭니다
- 는 지속 새로 P 있도록 ersisted 세션은이 테이블을 자동으로 업데이트합니다.
- 새 쿼리는이 테이블에서 사용자의 모든 친구에 대한 모든 레코드를 가져와 최종 결과를 만들기 위해 작업합니다.
열 솔루션은 세션 테이블에 "최신"플래그 열을 유지한다고 말합니다. 이 솔루션의 의미는 다음과 같습니다
- 는
- 열이 우편으로 설정됩니다 세션 엔티티의 지속 최신 (부울)에 대한 새 필드를 만들기 전 "최신"세션 수 있도록 더 이상 최신 세션이 아니며 새로운 세션이 최신 세션이됩니다.
- 새로운 쿼리는 최종 결과를 생성하는 그들에 원래 세션 테이블과 직장에서 사용자의 모든 친구 (명령문의 조건에 새 열을 포함하여) 모든 최신 기록을 가져옵니다.
각각에 장단점이 있으며 아직 우승자가 없습니다. 분명히 우리가 고려하지 않은 다른 해결책이있을 수 있습니다. 제가보기를 원하는 것은 위에 열거 된 것 중 무엇이 더 좋고, 왜, 또는 더 나은 접근 방법인지에 있습니다.
우정을위한 DB가 다른 이유는 무엇입니까? 정말 다른 DB 또는 다른 스키마입니까? – Unreason
기능이있는보기를 사용하는 방법은 어떻습니까? 가능한 경우 캐싱이 큰 도움이 될 수 있습니다. –
필자가 이해하는 한, 뷰는 복잡한 쿼리를 어떤 방식 으로든 실행하기 때문에 DB 업데이트 중에 더 많은 관리를 수행하여 쿼리의 성능을 향상시켜 이러한 상황을 피하려고합니다. –