이번 문서에서는 앞서 나열된 PostgreSQL 16 Release의 주요 변경내용 중 일부를 테스트한 내용을 기술합니다.
[성능 개선] FULL OUTER JOIN 및 RIGHT OUTER JOIN의 병렬 처리
PostgreSQL 16 버전부터 FULL OUTER JOIN 및 RIGHT OUTER JOIN의 병렬 처리를 지원함에 따라 Query Planner가 기존 버전 보다 더 효율적인 실행계획을 수립할 수 있습니다.
📢 병렬 처리는
enable_parallel_hash 파라미터로 제어할 수 있습니다.[성능 개선] 집계 함수의 병렬 처리
대용량 데이터에 대한 집계 함수(Aggregation Function)를 병렬 및 분산 방식으로 처리하여 쿼리 실행 속도를 높일 수 있습니다. 집계 함수에 대한 병렬 처리가 가능 함에 따라 Query Planner가 기존 버전 보다 더 효율적인 실행계획을 수립할 수 있습니다.
동일 SQL에 대해 PostgreSQL 15와 16의 Cost를 비교 하면 PostgreSQL 16 버전의 최종 Cost는 133493.19이고 PostgreSQL 15 버전의 최종 Cost는 242301.64 입니다. 비용 측면에서 성능 개선이 있음을 확인 할 수 있습니다.
[사용 편의성] Subquery Alias 불필요
PostgreSQL 15 버전까지는 Subquery Alias를 지정하지 않으면 에러가 발생하였지만, PostgreSQL 16 버전부터는 Alias를 지정하지 않아도 에러가 발생하지 않습니다.
[사용 편의성] 숫자 형식의 천 단위 구분자 적용
PostgreSQL 16 버전부터 언더스코어(_)를 사용하여 숫자 형식을 천 단위로 구분하여 사용할 수 있습니다.
[사용 편의성] psql의 \bind 명령어 추가
psql의
\bind 명령어가 추가되어 매개변수를 포함한 쿼리 수행 가능합니다.📢 16버전의 psql을 사용하여 PostgreSQL 15 버전에 접근할 경우 \bind 명령어를 사용할 수 있습니다.
[사용 편의성] libpq를 사용하는 Client의 Load Balancing
PostgreSQL 10 버전 부터 libpq를 사용하는 모든 Client는 여러 호스트를 연결할 수 있는 기능을 제공하였습니다.
이 예제에서 10.10.45.240:5432, 10.10.45.241:5433, 10.10.45.242:5434 순서로 연결 시도를 합니다.
PostgreSQL 16 버전 부터 load_balance_hosts 파라미터와 PGLOADBALANCEHOSTS 환경 변수가 생겼으며, 이를 통해 무작위 연결을 시도할 수 있습니다.
random: 나열된 연결 정보를 무작위로 연결 시도
disable: 기존 방식으로 연결 시도(순차적 연결)
더 가중치를 부여할 서버가 있는 경우 여러 번 나열하여 사용할 수 있습니다.
[Monitoring] last_seq_scan & last_idx_scan 컬럼 추가
PostgreSQL 16 버전에는 테이블의 Last Sequentail Scan및 Last Index Scan을 수행한 시간을 기록합니다. pg_stat_*_tables에는 last_seq_scan과 last_idx_scan 컬럼이 추가 되었고, pg_stat_*_indexes에는 last_idx_scan 컬럼이 추가되었습니다. 이 컬럼들은 오버헤드를 최소화 하기 위하여 트랜잭션 커밋 시에만 업데이트 됩니다. last_idx_scan 컬럼을 통해 불필요한 인덱스를 식별하고, last_seq_scan 컬럼을 통해 새 인덱스의 필요성을 식별하는데 도움을 받을 수 있습니다.
[Monitoring] pg_stat_io Catalog
PostgreSQL 15 버전까지
pg_stat_database, pg_statio_all_tables, pg_statio_all_indexes, pg_stat_bgwriter, pg_stat_statements 등의 Catalog를 통해 I/O 통계를 확인 및 분석 할 수 있었습니다. 하지만 위에 나열된 Catalog에서는 아래와 같은 이유로 정확한 I/O 측정을 할 수 없습니다.- Writes 포함 내용 (Writes = Flushes + extends)
- Backend Type 별 Reads, Write 확인 불가 (모든 backend types을 통합해서 표시)
- contexts(I/O 작업)와 object(저장 유형)에 따른 통계 확인 불가 (모든 contexts와 objects를 통합해서 표시)
PostgreSQL 16 버전에는 I/O Access Pattern을 세부적으로 분석할 수 있는
pg_stat_io 도입되었습니다. track_io_timing = on으로 설정하면 pg_stat_io System View를 통해 I/O 성능 문제를 추적하는데 용이합니다.
Column | Description |
backend_type | Backend Type. (e.g. background worker, client backend, walsender, standalone backend, autovacuum worker, autovacuum launcher, background writer, startup, checkpointer) |
object | I/O 대상(저장 유형). relation, temp relation |
context | I/O 작업. normal, vacuum, bulkread, bulkwrite |
reads | Read 작업 수 (크기 bytes = reads * op_bytes) |
read_time | Read 작업 소요 시간(ms) → track_io_timing = on 설정 필요(off 경우 0) |
writes | Write 작업 수 (크기 bytes = writes * op_bytes) |
write_time | Write 작업 소요 시간(ms) → track_io_timing = on 설정 필요(off 경우 0) |
writebacks | 커널에서 OS로 데이터 보낸 수 (크기 bytes = wirtebacks * op_bytes) |
writeback_time | writeback 작업 소요 시간(ms) → track_io_timing = on 설정 필요(off 경우 0) |
extends | Relation의 확장 수 (크기 bytes = extends * op_bytes) |
extend_time | Relation의 확장 작업 소요 시간(ms) → track_io_timing = on 설정 필요(off 경우 0) |
op_bytes | I/O 단위 당 크기. block_size Parameter로 정해지며 기본 값 = 8192 (8k) |
hits | Shared Buffer에서 원하는 Block을 찾은 횟수 |
evictions | 새로운 블록을 위해 공간 확보를 한 횟수 |
reuses | |
fsyncs | fsync 호출 횟수. normal context만 추적 가능 |
fsync_time | fsync 호출 소요 시간(ms) → track_io_timing = on 설정 필요(off 경우 0) |
stats_reset | 통계가 마지막으로 재설정된 시간 |
본 예시에서 test01 Table은 87번의 extends가 발생하였으며, 그 크기는 712,704 Byte(extends * op_bytes = 87 * 8192 = 712,704)입니다. 87번 extends 하면서 소요된 시간은 1.076ms 입니다. 실제 Table의 크기를 확인 해보면 아래와 같습니다.
extends가 발생하여 계산한 크기와 실제 Table의 크기가 24,576 Byte 차이가 있는 것을 확인할 수 있습니다.(712,704 - 688,128 = 24,576) 이 차이는 Free Space Map(FSM)의 크기로 pg_stat_io의 extends로 계산된 크기는 FSM 크기까지 포함 되어 있습니다.
추가적으로 pg_stat_io를 통해서 Cache Hit Ratio를 확인 할 수 있으며, 이를 통해 shared_buffer의 크기를 조정하는데 사용할 수 있습니다. Cache Hit Ratio는 pg_stat_database Catalog를 통해서도 확인 할 수 있지만 pg_stat_io와의 큰 차이는 Backend Type별로 확인이 가능한지 여부입니다.
[보안] 권한 부여를 위한 WITH ADMIN OPTION
PostgreSQL 16 버전부터는 CREATEROLE 속성(Attribute)이 있어도 WITH ADMIN OPTION 없이는 권한을 부여할 수 없습니다. PostgreSQL 15 버전까지는 CREATEROLE 권한이 있으면 권한 부여하는 것이 가능했습니다.
함께 보면 좋은 아티클
