현재 구조와 같은 링크 된 목록에서 마지막 decendet을 효율적으로 검색하려고합니다. |PostgreSQL은 선형 목록에서 마지막 decendant를 효율적으로 찾습니다.
는 기본적으로 나는이
current_id 같은 목록을 얻으려면 그것을 분할 특정 기준으로, 데이터 계열이있는 테이블있다 > - 2 -> 3 -> 4
및
42 -> 43 -> 45
next_id 예는
1 | 2
2 | 3
3 | 4
4 | NULL
42 | 43
43 | 45
45 | NULL
etc...
는
1과 같이 나열 초래
이제 각 목록에서 첫 번째와 마지막 ID를 가져 오려고합니다. 이 경우 주어진 데이터에 대해 잘 작동 나는 단지 사용 타임 스탬프에
WITH RECURSIVE contract(ruid, rdid, rstart_ts, rend_ts) AS (-- recursive Query to traverse the "linked list" of continuous timestamps
SELECT start_ts, end_ts FROM track_caps tc
UNION
SELECT c.rstart_ts, tc.end_ts AS end_ts0 FROM contract c INNER JOIN track_caps tc ON (tc.start_ts = c.rend_ts AND c.rend_ts IS NOT NULL AND tc.end_ts IS NOT NULL)
),
fcontract AS (--final step, after traversing the "linked list", pick the largest timestamp found as the end_ts and the smallest as the start_ts
SELECT DISTINCT ON(start_ts, end_ts) min(rstart_ts) AS start_ts, rend_ts AS end_ts
FROM (
SELECT rstart_ts, max(rend_ts) AS rend_ts FROM contract
GROUP BY rstart_ts
) sq
GROUP BY end_ts
)
SELECT * FROM fcontract
ORDER BY start_ts
:
이것은 내가 지금 가지고있는 것입니다.
기본적으로 StackOverflow 및 다른 사이트의 다른 많은 게시물에서 제안한 것처럼 모든 노드를 끝까지 반복적으로 탐색하는 재귀 쿼리를 사용합니다. 다음 쿼리는 모든 하위 단계를 제거하고 첫 번째 목록 예와 같이 내가 원하는 것을 반환합니다. 1 | 그냥 그림 4
는 재귀 쿼리가 설정 한 생산 결과는 다음과 같습니다
1 | 2
2 | 3
3 | 4
1 | 3
2 | 4
1 | 4
을 같이 잘 작동으로,이 결과를 볼 때 절대적으로 놀랍지 그러나 꽤 메모리 돼지입니다 EXPLAIN ANALYZE
. 대략 42,600 개의 행으로 구성된 데이터 집합의 경우 재귀 쿼리는 무려 849,542,346 개의 행을 생성합니다. 이제 실제로 실제로 약 2,000,000 행을 처리하기로되어 있었지만 지금 당장은이 솔루션을 사용하면 매우 실용적이지 않은 것처럼 보입니다.
부적절하게 재귀 쿼리를 사용 했습니까? 생성하는 데이터의 양을 줄이는 방법이 있습니까? (하위 단계 제거와 같은) 또는이 문제에 대한 단일 쿼리 솔루션이 있습니까?
어쩌면 내가 부족 뭔가하지만 간단하지 않다'next_id 어디 null'되지 않는 이유는 무엇입니까? –
@a_horse_with_no_name하지만 where 절로 선택된 마지막 ID에 속하는 목록의 맨 처음 ID는 어떻게 얻을 수 있습니까? –