PostgreSQL의 다중 열 btree 색인을 활용하여 두 테이블 간의 성가신 조인을 수행하려고합니다.비교 ("<" and ">") 연산자를 사용하는 PostgreSQL 다중 열 색인 결합
Table "revision_main"
Column | Type | Modifiers
----------------+------------------------+-----------
revision_id | integer |
page_id | integer |
Indexes:
"revision_main_pkey" UNIQUE, btree (revision_id)
"revision_main_cluster_idx" btree (page_id, "timestamp") CLUSTER
이 표에는 위키의 페이지에 대한 수정본 (~ 300 백만 행)이 포함되어 있습니다. 내 테이블에는 더 많은 열이 있지만, 중요하지 않아야하므로이 예제에서는 제외했습니다.
Table "revert"
Column | Type | Modifiers
--------------------+---------+-----------
page_id | integer |
revision_id | integer |
reverted_to | integer |
Indexes:
"revert_page_between_idx" btree (page_id, reverted_to, revision_id) CLUSTER
이 표에는 되돌리기 버전 (2200 만 줄)이 포함되어 있습니다. 리비전이 되돌려 진 경우 revision_id는 revision_main 테이블에 행을 가지며 revision_id와 revision_id 사이에 revision_id가 있으며 동일한 page_id를 공유합니다. 호기심이 있다면 http://en.wikipedia.org/wiki/Wikipedia:Revert을 참조하십시오.
복귀 된 개정판을 얻기 위해이 두 테이블에 합류하는 것은 간단합니다.
이explain SELECT
r.revision_id,
rvt.revision_id
FROM revision_main r
INNER JOIN revert rvt
ON r.page_id = rvt.page_id
AND r.revision_id > rvt.reverted_to
AND r.revision_id < rvt.revision_id;
QUERY PLAN
----------------------------------------------------------------------------------------------------
Merge Join (cost=4202878.87..15927491478.57 rows=88418194298 width=8)
Merge Cond: (r.page_id = rvt.page_id)
Join Filter: ((r.revision_id > rvt.reverted_to) AND (r.revision_id < rvt.revision_id))
-> Index Scan using revision_main_page_id_idx on revision_main r (cost=0.00..9740790.61 rows=223163392 width=8)
-> Materialize (cost=4201592.06..4536465.21 rows=26789852 width=12)
-> Sort (cost=4201592.06..4268566.69 rows=26789852 width=12)
Sort Key: rvt.page_id
-> Seq Scan on revert rvt (cost=0.00..438534.52 rows=26789852 width=12)
(">"때문에 "<"와 같은 비교 연산자를 지원)를 BTREE 인덱스해야 되돌리기에 클러스터 된 인덱스, 쿼리 최적화하지 않더라도 : 여기로 왔어요 것입니다 참여에 대한 색인을 사용하고 "explain"은 총 비용이 150 억이 넘을 것으로 예측합니다 (내년에 완료 될 수 있음).
비교 연산자는 다중 열 (btree) 인덱스와 함께 사용할 수 없습니까? 내가 잘못하고있는거야?
난 그냥 인덱스를 사용하는 것보다 더 빠르게 할 수있는 전체 테이블을 정렬하는 방법을 볼 수 있습니다 ,하지만 내 경험에 의하면 비용 견적은 실행 시간을 일관되게 반영하는 경향이 있습니다. 반면에, 나는 그 숫자가 무엇을 의미하는지 결코 알지 못했습니다. 그래서 당신의 이해를 인정할 것입니다. 당신은 단지 쿼리를 실행하고 숫자를 무시해야한다고 제안하고 있습니까? – halfak
@halfak : 자세히 살펴 보겠습니다. 데이터베이스는 작은 테이블로 조인을 시작하는 것과 같습니다. revision_main에 (page_id, revision_id)에 인덱스를 추가하면보다 효율적인 쿼리를 얻을 수 있습니다. 그것은 또한 더 나쁠 수도 있습니다. 그러나 이것이 실패 할 경우, 훨씬 더 효율적이되도록하는 유일한 방법은 더 적은 데이터를 요구하는 방법을 찾는 것입니다. – btilly