INSERT INTO ... SELECT 쿼리의 SELECT 부분에 병렬 실행을 사용하면 특히 파티션을 나눈 테이블과 복잡한 쿼리의 경우 PostgreSQL용 AlloyDB 쿼리 성능을 개선할 수 있습니다.
SELECT 하위 계획을 병렬화하면 데이터베이스에서 여러 작업자 프로세스를 사용하여 데이터를 가져옵니다. 그러면 데이터베이스가 검색된 데이터를 대상 테이블에 삽입합니다. 이러한 분업을 통해 데이터베이스 성능을 개선할 수 있습니다.
PostgreSQL의 병렬 쿼리 계획 작동 방식
PostgreSQL에서 쿼리 옵티마이저는 전체 쿼리 또는 쿼리의 일부에 대한 병렬 계획을 만들 수 있습니다. 병렬 계획이 생성되면 계획의 상단에 Gather 또는 Gather Merge 노드가 추가됩니다.
이 노드는 여러 병렬 작업자 프로세스를 조정합니다. 각 작업자는 작업의 일부(예: 테이블의 일부 스캔)를 실행합니다. 그런 다음 Gather 노드는 모든 작업자의 결과를 수집하여 쿼리의 다음 단계로 전달하거나 클라이언트로 다시 전달합니다.
예를 들어 다음 쿼리 계획은 t1 테이블에서 병렬 순차 스캔을 위해 작업자 프로세스 5개를 사용할 계획인 Gather 노드를 보여줍니다.
EXPLAIN SELECT * FROM t1;
QUERY PLAN
-------------------------------------------------------------
Gather (cost=0.00..143359.76 rows=9999878 width=60)
Workers Planned: 5
-> Parallel Seq Scan on t1 (cost=0.00..143359.76 rows=1999976 width=60)
(3 rows)
INSERT...SELECT 문의 병렬 실행
AlloyDB는 여러 작업자 프로세스를 사용해 SELECT 문을 병렬화하여 INSERT INTO ... SELECT 성능을 향상합니다.
이러한 분업을 통해 데이터베이스 성능을 개선할 수 있습니다.
쿼리는 병렬로 안전해야 하며 병렬화를 방지하는 조건이 없어야 합니다.
많은 데이터베이스 작업에서 INSERT INTO ... SELECT 문을 사용하여 테이블에 새 행을 추가합니다. 문장의 SELECT 부분이 쿼리에서 리소스가 가장 많이 사용되는 부분인 경우가 많습니다.
이 기능은 다음 구성 파라미터에 의해 제어됩니다.
enable_parallel_select_for_insert_select: 기능을 사용 설정 또는 중지합니다. 이 파라미터는 PostgreSQL 14 이상에서 기본적으로 사용 설정되어 있습니다.enable_parallel_select_for_insert_select_into_part_table: 파티션을 나눈 테이블에 삽입할 수 있는 기능을 사용 설정하거나 사용 중지합니다. 이 파라미터는 PostgreSQL 16 이상에서 기본적으로 사용 중지되어 있습니다.
쿼리 플래너가 병렬 계획을 고려하려면 INSERT SELECT 문이 병렬 안전해야 합니다. 즉, 작업의 어떤 부분에도 병렬로 안전하게 실행할 수 없는 함수나 표현식이 포함될 수 없습니다. 쿼리의 일부가 병렬로 안전하지 않은 것으로 확인되면 옵티마이저는 비병렬 계획으로 대체됩니다. 자세한 내용은 parallel-safety를 참조하세요.
병렬 실행 방지 조건
INSERT SELECT 문이 병렬로 안전하지 않은 것으로 간주되면 쿼리 최적화 프로그램은 병렬 계획을 사용하지 않습니다. 다음 조건에서는 병렬화가 불가능합니다.
- 대상 테이블이 외래 테이블입니다.
- 쿼리에서 데이터 수정 문(예:
DELETE)이 포함된 수정 가능한 공통 테이블 표현식(CTE)을 사용합니다. - 대상 테이블의 색인이 병렬로 안전하지 않은 표현식이나 함수를 사용합니다.
- 대상 테이블의 열에 병렬로 안전하지 않은 함수를 사용하는 기본값이 있습니다.
- 대상 테이블의 트리거가 병렬로 안전하지 않은 표현식이나 함수를 사용합니다.
- 대상 테이블에 병렬로 안전하지 않은 함수를 사용하는
CHECK제약 조건이 있는 DOMAIN 열이 있습니다. - 대상 테이블의
CHECK제약 조건에 병렬로 안전하지 않은 표현식이나 함수가 포함되어 있습니다. - 대상 테이블이 파티션을 나눈 테이블이고
enable_parallel_select_for_insert_select_into_part_table이 사용 중지되어 있습니다.
시작하기 전에
이 문서에서는 AlloyDB 데이터베이스가 있다고 가정합니다. 데이터베이스를 만들려면 클러스터 및 클러스터의 기본 인스턴스 만들기 및 데이터베이스 만들기 및 관리를 참조하세요.
필요한 역할
세션 수준에서 데이터베이스 플래그를 변경하는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 AlloyDB 데이터베이스 사용자(roles/alloydb.databaseUser) Identity and Access Management(IAM) 역할을 부여해 달라고 요청하세요. 역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.
병렬 실행 파라미터 사용 설정
파티션을 나눈 대상 테이블의 병렬 실행을 사용 설정하려면 다음 단계를 따르세요.
Google Cloud 콘솔에서 클러스터 페이지로 이동합니다.
목록에서 클러스터를 선택합니다.
탐색 메뉴에서 AlloyDB Studio를 클릭합니다.
데이터베이스 이름, 사용자 이름, 비밀번호를 사용하여 AlloyDB Studio에 로그인합니다.
enable_parallel_select_for_insert_select_into_part_tableGUC를on으로 설정합니다.SET enable_parallel_select_for_insert_select_into_part_table = on;GUC 파라미터를 사용 설정하면 쿼리가 병렬로 안전한 것으로 확인되는 경우 쿼리 플래너는 타겟이 파티션된 테이블인
INSERT INTO ... SELECT문의 병렬 계획을 자동으로 고려합니다.다음 예시에서는
source_table의SELECT가 병렬로 실행됨을 나타내는 Gather 노드를 보여주는 EXPLAIN 계획이 생성됩니다.-- Create a partitioned table CREATE TABLE part_table (a INT, b TEXT) PARTITION BY RANGE (a); CREATE TABLE part_table_1 PARTITION OF part_table FOR VALUES FROM (MINVALUE) TO (1000); CREATE TABLE part_table_2 PARTITION OF part_table FOR VALUES FROM (1000) TO (MAXVALUE); -- Create a source table CREATE TABLE source_table (c1 INT, c2 TEXT); INSERT INTO source_table SELECT i, 'value_' || i FROM generate_series(1, 2000) i; ANALYZE source_table; -- Enable the feature SET enable_parallel_select_for_insert_select_into_part_table = on; -- Optional for parallelizing the query with a small amount of data SET parallel_setup_cost=0; SET parallel_tuple_cost=0; SET min_parallel_table_scan_size=0; -- Run the insert with a parallelizable select EXPLAIN INSERT INTO part_table SELECT * FROM source_table;그러면 다음과 같은 출력이 반환됩니다.
EXPLAIN (COSTS OFF) INSERT INTO part_table SELECT * FROM source_table; QUERY PLAN ----------------------------------------------- Insert on part_table -> Gather Workers Planned: 2 -> Parallel Seq Scan on source_table (4 rows)
병렬 실행 파라미터 사용 중지
파라미터를 사용 중지하려면 다음 단계를 따르세요.
Google Cloud 콘솔에서 클러스터 페이지로 이동합니다.
목록에서 클러스터를 선택합니다.
탐색 메뉴에서 AlloyDB Studio를 클릭합니다.
데이터베이스 이름, 사용자 이름, 비밀번호를 사용하여 AlloyDB Studio에 로그인합니다.
enable_parallel_select_for_insert_select파라미터를 사용 중지하려면 다음 SQL 명령어를 실행합니다.SET enable_parallel_select_for_insert_select = OFF;enable_parallel_select_for_insert_select_into_part_table파라미터를 사용 중지하려면 다음 SQL 명령어를 실행합니다.SET enable_parallel_select_for_insert_select_into_part_table = OFF;
병렬 계획 확인
EXPLAIN 명령어를 사용하여 옵티마이저가 병렬 계획을 사용하는지 확인할 수 있습니다. 쿼리 계획에서 Gather 노드와 Workers Planned 또는 Workers Launched 속성을 찾습니다.
표준 테이블 예시
다음 계획 예시에서는 SELECT 문을 실행하기 위한 병렬 해시 조인을 위해 작업자 프로세스 6개가 실행됩니다.
EXPLAIN (ANALYZE)
INSERT INTO t1 SELECT t2.* FROM t1, t2 WHERE t1.c1 != t2.c1 AND t1.c2 = t2.c2;
QUERY PLAN
------------------------------------------------------------------------------------
Insert on t1 (cost=1209138.00..12801765.49 rows=0 width=0) (actual time=16812.677..19337.150 rows=0 loops=1)
-> Gather (cost=1209138.00..12801765.49 rows=99995407 width=24) (actual time=16812.674..19337.144 rows=0 loops=1)
Workers Planned: 6
Workers Launched: 6
-> Parallel Hash Join (...)
(...)
파티션을 나눈 테이블 예시
다음 예에서는 파티션 테이블의 기능을 사용 설정한 후 계획에 SELECT에 대해 계획된 작업자가 4명인 Gather 노드가 표시됩니다.
-- First, enable the feature for partitioned tables
SET enable_parallel_select_for_insert_select_into_part_table = ON;
-- Then, explain the query
EXPLAIN (COSTS OFF) INSERT INTO part_table SELECT * FROM source_table;
QUERY PLAN
-----------------------------------------------
Insert on part_table
-> Gather
Workers Planned: 2
-> Parallel Seq Scan on source_table
(4 rows)
다음 단계
- 병렬 안전성에 대해 자세히 알아보기