VACUUM FULL과 CLUSTER의 PostgreSQL 차이점


13

데이터가 차지하는 200GB 크기의 테이블과 6 개의 인덱스로 180GB 크기의 테이블이 있습니다. 30 % 팽만감으로 인해 차지하는 불필요한 공간을 되찾고 싶습니다. job_id_idx 인덱스에 클러스터됩니다 .

공간을 되 찾으려면 cluster명령 또는 vacuum full명령 을 사용해야 합니까?

  1. 이 두 명령의 차이점은 무엇입니까?

  2. 인가 vacuum full와 같은 일부 열을 기준으로 순서 cluster명령은?

  3. 두 명령 모두에서 색인이 다시 작성됩니까?

  4. 제 경우에는 어느 것이 더 빠를까요?

PostgreSQL 데이터베이스 버전은 9.1입니다.


1
예, 인덱스가 다시 작성됩니다. 더 빠른 것은 몇 가지 사항에 달려 있다고 생각합니다. 그러나 한 가지 확실한 점은 '일부 열에 의한 진공 전체 순서'와 같은 것은 없습니다.
dezso

1
VACUUM을 트랜잭션 내에서 실행할 수없는 경우가 많으며, 이로 인해 많은 경우 CLUSTER가 유사한 결과를 생성하는 더 나은 대안 (때로는 유일한 대안)이됩니다.
oᴉɹǝɥɔ

답변:


8

무엇을 확인하기 위해 CLUSTER초기 실험에서 기본적으로 첫 천만개의 양의 정수를 포함하는 표를 가져 왔습니다. 이미 일부 행을 삭제하고 다른 열도 있지만 실제 테이블 크기에만 영향을 미치므로 흥미롭지 않습니다.

먼저 VACUUM FULL테이블 fka에서 실행 하면서 크기를 가져 왔습니다.

\dt+ fka
                    List of relations
 Schema | Name | Type  |  Owner   |  Size  | Description 
--------+------+-------+----------+--------+-------------
 public | fka  | table | test     | 338 MB | 

그런 다음 테이블의 맨 처음부터 데이터의 물리적 순서를 봅시다.

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   5 | 5    | (0,4)
   6 | 6    | (0,5)

이제 일부 행을 삭제하겠습니다 :

DELETE FROM fka WHERE id % 10 = 5;
--DELETE 1000000

이 후에도보고 된 테이블 크기는 변경되지 않았습니다. 이제 무엇을하는지 보자 CLUSTER.

CLUSTER fka USING fka_pkey;

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   6 | 6    | (0,4)
   7 | 7    | (0,5)

작업 후 테이블 크기가 338MB에서 296MB로 변경되었습니다. ctid페이지에서 튜플의 실제 위치를 설명 하는 열에서 행 일치와의 간격이 없다는 id = 5것을 알 수 있습니다.

튜플이 재정렬되면 인덱스가 올바른 위치를 가리 키도록 다시 작성되어야합니다.

따라서 차이점은 VACUUM FULL행을 정렬하지 않는 것 같습니다. 내가 아는 한, 두 명령이 사용하는 메커니즘에는 약간의 차이가 있지만 실제적인 관점에서 이것은 주된 (단지?) 차이로 보입니다.


나는 ctid열이 무엇인지 확신하지 못했습니다 . 그것이 테이블 내 행의 물리적 위치를 설명하는 시스템 열임을 알 수 있습니다. postgresql.org/docs/current/ddl-system-columns.html
Gajus

8

VACUUM FULL추가 공간없이 테이블의 전체 내용을 새 디스크 파일로 다시 작성하여 사용되지 않은 공간을 운영 체제로 반환 할 수 있습니다. 이 방법은 테이블의 새 복사본을 작성하고 작업이 완료 될 때까지 이전 복사본을 해제하지 않기 때문에 추가 디스크 공간이 필요합니다. 일반적으로 이는 테이블 내에서 많은 양의 공간을 확보해야하는 경우에만 사용해야합니다.

http://www.postgresql.org/docs/9.1/static/sql-vacuum.html

CLUSTERindex_name으로 지정된 색인을 기반으로 table_name으로 지정된 테이블을 클러스터하도록 PostgreSQL에 지시합니다. 인덱스는 이미 table_name에 정의되어 있어야합니다. 테이블이 클러스터링되면 인덱스 정보를 기준으로 테이블이 물리적으로 재정렬되고 ACCESS EXCLUSIVE 잠금이 획득됩니다.

http://www.postgresql.org/docs/9.1/static/sql-cluster.html

또한 intresting : is-a-reindex-required-after-cluster

그러나 REINDEX인덱스 테이블에 저장된 데이터를 사용하여 인덱스를 다시 작성하여 인덱스의 이전 사본을 대체 하는 간단한 것만 있으면됩니다.

http://www.postgresql.org/docs/9.1/static/sql-reindex.html


1
우와! REINDEX에 대한 좋은 팁! 나는 VACUUM과 CLUSTER에 의해 몇 개의 테이블을 축소하고 (라이브를 수행하는 데 시간과 영향을 비교하려고 시도) 현재 가장 큰 객체는 실제로 인덱스입니다.
mike
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.