Vacuum 수행 시 index 동작
개요
해당 문서는 Vacuum 수행 시 인덱스 정리를 함께 해주는 기능이나 방법이 있다면,
“단순히 Vacuum 을 수행하는 방안과 Vacuum 전에 Index Drop 후 VACUUM 또는 VACUUM FULL 수행 후 Index 를 재생성 하는 방식으로 성능 상의 이점을 챙길 수 있을까?” 의 내용을 기술한 문서입니다.
Vacuum 수행 시에 인덱스를 정리해주는 기능을 알아보고, 기능들을 사용해보면서 성능 상의 이점이 있는지 테스트를 통해 확인해보겠습니다.
- 첫째로, VACUUM 을 수행 시 옵션으로 줄 수 있는 INDEX_CLEANUP 옵션이 있습니다. 해당 옵션을 on 으로 사용하게 되면 Vacuum 작업 시 데드 튜플이 0개 보다 많을 경우에 Index 정리를 강제로 수행할 수 있습니다.
- 둘째로, VACUUM FULL 수행 시에는 완료 최종 단계 전에 Rebuilding Index 수행 단계로 Reindex 를 수행하는 과정이 포함되어 있습니다.
테스트 시나리오
이제 테스트를 수행해보겠습니다. 테스트 시나리오는 아래와 같습니다.

이제 테스트 시나리오를 따라서 환경 구축을 한 뒤 테스트를 진행해보겠습니다.
PostgreSQL 설정은 아래와 같이 파라미터를 구성하였습니다.


테스트 대상 테이블과 인덱스를 생성합니다. Update 를 수행하여, 데드 튜플을 발생시켰습니다.
- 시나리오 1-1 ( Index Drop 없이 VACUUM 을 수행하여 데드튜플 정리와 인덱스 재정리를 함께 수행합니다. )

- 시나리오 1-2 ( Index 삭제, VACUUM 수행 후 Index 재생성합니다. )

- 시나리오 2-1 ( Index Drop 없이 VACUUM FULL 수행하여 데드 튜플을 제거하고 인덱스 리빌드를 수행합니다. )

- 시나리오 2-2 ( Index 삭제, VACUUM FULL 수행 후 Index 재생성합니다. )

테스트 결과
- 각각의 시나리오 수행시간 결과입니다. 두 가지 서버로 테스트를 해보았습니다.
- 서버에 따라 수행 시간 차이가 날 수 있으나, 각각의 시나리오에 대한 수행 시간 비교를 해주시면 되겠습니다.
- 테스트 서버 1
- Spec : 8core 32Memory + SSD
seq | 시나리오 1-1 | 시나리오 1-2 |
1 | 0:03:46 | 0:02:23 |
2 | 0:03:42 | 0:02:26 |
3 | 0:03:53 | 0:02:00 |
4 | 0:03:44 | 0:01:57 |
5 | 0:03:47 | 0:03:01 |
… | … | … |
AVG | 0:03:46 | 0:02:21 |
seq | 시나리오 1-1 | 시나리오 1-2 |
1 | 0:03:52 | 0:05:31 |
2 | 0:04:32 | 0:03:40 |
3 | 0:05:28 | 0:04:37 |
4 | 0:04:19 | 0:06:38 |
5 | 0:06:29 | 0:03:55 |
… | … | … |
AVG | 0:04:56 | 0:04:52 |
- 테스트 서버 2
- Spec : 8core 32Memory + HDD
seq | 시나리오 1-1 | 시나리오 1-2 |
---|---|---|
1 | 0:14:27 | 0:12:11 |
2 | 0:13:08 | 0:10:01 |
3 | 0:13:16 | 0:10:34 |
4 | 0:13:30 | 0:10:41 |
5 | 0:15:19 | 0:12:20 |
… | … | … |
AVG | 0:13:56 | 0:11:09 |
seq | 시나리오 2-1 | 시나리오 2-2 |
---|---|---|
1 | 0:05:41 | 0:06:22 |
2 | 0:05:39 | 0:04:51 |
3 | 0:06:13 | 0:05:16 |
4 | 0:06:51 | 0:05:30 |
5 | 0:05:30 | 0:06:42 |
… | … | … |
AVG | 0:05:59 | 0:05:44 |
결론
결과를 확인해보면, 시나리오 1-1과 1-2는 VACUUM 수행 간에 인덱스를 정리하는 기능을 강제로 사용하는 방식과 인덱스의 재생성의 성능 비교를 위한 테스트를 진행했습니다.
시나리오 1-2 같은 경우 약 20% 정도의 성능 차이를 보여주고 있습니다. (SSD, HDD DISK I/O 속도에 따라 결과 상이)
INDEX_CLEANUP 수행 과정이 포함되면 기존 인덱스 데드 튜플을 재정리하는 과정이 포함되므로, 그만큼 DISK I/O 가 다량 발생하게되며 인덱스를 삭제하고 재생성하는 것에서 더 빠른 수행이 가능한 것을 확인할 수 있습니다.
하지만, 시나리오 1-2와 같은 방식은 테이블과 인덱스의 개수가 적어서 간단한 수행이 필요한 경우가 아니라면 권장할 수 없습니다.
이유는, 인덱스를 삭제하고 재생성하는 과정에서 관리자의 더 많은 번거로움이 발생할 것이며, 더 많은 시간이 소요될 수 있습니다. 또한, 시나리오 1-2와 같이 인덱스를 삭제한다는 것은 서비스 운영 중 수행한다는건 사실상 불가능하기 때문에 VACUUM 을 수행하는게 합리적입니다.
시나리오 2-1과 2-2의 경우 VACUUM FULL 의 수행이므로 서비스 중엔 수행이 불가능합니다. 또한, 성능 차이도 거의 없기 때문에, 인덱스를 삭제하고 생성하는 번거로움을 겪기보다 단순히 VACUUM FULL 을 수행하는 것이 효율적입니다.
종합적으로 VACUUM 의 목적 자체를 확실히 하여 데드 튜플 정리가 필요하다면 VACUUM 을 수행할 것이며, 인덱스 재정리가 필요하다면 REINDEX 를 따로 수행할 수 있으므로 위와 같이 인덱스를 삭제하고 새롭게 생성하는 케이스의 수행은 권장하지 않습니다.
감사합니다.