테이블 파티션 지원
Aurora PostgreSQL 쿼리 계획 관리(QPM)는 다음 버전에서 선언적 테이블 파티셔닝을 지원합니다.
15.3 이상의 15 버전
14.8 이상의 14 버전
13.11 이상의 13 버전
자세한 내용은 테이블 파티셔닝
테이블 파티션 설정
Aurora PostgreSQL QPM에서 테이블 파티션을 설정하려면 다음 작업을 수행합니다.
DB 클러스터 파라미터 그룹에서
apg_plan_mgmt.plan_hash_version
을 3 이상으로 설정합니다.쿼리 계획 관리를 사용하고
apg_plan_mgmt.dba_plans
보기에 항목이 있는 데이터베이스로 이동합니다.apg_plan_mgmt.validate_plans('update_plan_hash')
를 호출하여 계획 테이블의plan_hash
값을 업데이트합니다.apg_plan_mgmt.dba_plans
보기에 항목이 있으며 쿼리 계획 관리가 활성화된 모든 데이터베이스에 대해 2~3단계를 반복합니다.
이런 파라미터에 대한 자세한 내용은 Aurora PostgreSQL 쿼리 계획 관리를 위한 파라미터 참조 섹션을 참조하세요.
테이블 파티션에 대한 계획 캡처
QPM에서는 다양한 계획이 plan_hash
값으로 구분됩니다. plan_hash
가 어떻게 변하는지 이해하려면 먼저 비슷한 종류의 계획을 이해해야 합니다.
계획이 동일한 것으로 간주되려면 Append 노드 수준에서 누적된 액세스 방법, 숫자 제거 인덱스 이름 및 숫자 제거 파티션 이름의 조합이 일정해야 합니다. 계획에서 액세스하는 특정 파티션은 중요하지 않습니다. 다음 예제에서는 파티션이 4개인 tbl_a
테이블이 생성됩니다.
postgres=>
create table tbl_a(i int, j int, k int, l int, m int) partition by range(i);CREATE TABLE
postgres=>
create table tbl_a1 partition of tbl_a for values from (0) to (1000);CREATE TABLE
postgres=>
create table tbl_a2 partition of tbl_a for values from (1001) to (2000);CREATE TABLE
postgres=>
create table tbl_a3 partition of tbl_a for values from (2001) to (3000);CREATE TABLE
postgres=>
create table tbl_a4 partition of tbl_a for values from (3001) to (4000);CREATE TABLE
postgres=>
create index t_i on tbl_a using btree (i);CREATE INDEX
postgres=>
create index t_j on tbl_a using btree (j);CREATE INDEX
postgres=>
create index t_k on tbl_a using btree (k);CREATE INDEX
다음 계획은 쿼리에서 조회하는 파티션 수에 관계없이 단일 스캔 방법을 사용하여 tbl_a
를 스캔하기 때문에 동일한 것으로 간주됩니다.
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 999 and j < 9910 and k > 50;QUERY PLAN ------------------------------------------------------------------- Seq Scan on tbl_a1 tbl_a Filter: ((i >= 990) AND (i <= 999) AND (j < 9910) AND (k > 50)) SQL Hash: 1553185667, Plan Hash: -694232056 (3 rows)
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;QUERY PLAN ------------------------------------------------------------------- Append -> Seq Scan on tbl_a1 tbl_a_1 Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50)) SQL Hash: 1553185667, Plan Hash: -694232056 (6 rows)
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;
QUERY PLAN -------------------------------------------------------------------------- Append -> Seq Scan on tbl_a1 tbl_a_1 Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50)) -> Seq Scan on tbl_a3 tbl_a_3 Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50)) SQL Hash: 1553185667, Plan Hash: -694232056 (8 rows)
상위 수준에서 액세스 방법, 숫자 제거 인덱스 이름 및 숫자 제거 파티션 이름이 SeqScan tbl_a
, IndexScan (i_idx) tbl_a
이므로 다음 3가지 계획도 동일한 것으로 간주됩니다.
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Seq Scan on tbl_a1 tbl_a_1 Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50)) -> Index Scan using tbl_a2_i_idx on tbl_a2 tbl_a_2 Index Cond: ((i >= 990) AND (i <= 1100)) Filter: ((j < 9910) AND (k > 50)) SQL Hash: 1553185667, Plan Hash: -993736942 (7 rows)
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1 Index Cond: ((i >= 990) AND (i <= 2100)) Filter: ((j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50)) -> Index Scan using tbl_a3_i_idx on tbl_a3 tbl_a_3 Index Cond: ((i >= 990) AND (i <= 2100)) Filter: ((j < 9910) AND (k > 50)) SQL Hash: 1553185667, Plan Hash: -993736942 (10 rows)
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 3100 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Seq Scan on tbl_a1 tbl_a_1 Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50)) -> Seq Scan on tbl_a3 tbl_a_3 Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50)) -> Index Scan using tbl_a4_i_idx on tbl_a4 tbl_a_4 Index Cond: ((i >= 990) AND (i <= 3100)) Filter: ((j < 9910) AND (k > 50)) SQL Hash: 1553185667, Plan Hash: -993736942 (11 rows)
하위 파티션의 순서 및 발생 횟수에 관계없이 액세스 방법, 숫자 제거 인덱스 이름 및 숫자 제거 파티션 이름은 위의 각 계획에 대해 상위 수준에서 일정합니다.
그러나 다음 조건 중 하나라도 충족되면 계획이 다른 것으로 간주됩니다.
-
계획에 추가 액세스 방법이 사용됩니다.
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Seq Scan on tbl_a1 tbl_a_1 Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50)) -> Bitmap Heap Scan on tbl_a3 tbl_a_3 Recheck Cond: ((i >= 990) AND (i <= 2100)) Filter: ((j < 9910) AND (k > 50)) -> Bitmap Index Scan on tbl_a3_i_idx Index Cond: ((i >= 990) AND (i <= 2100)) SQL Hash: 1553185667, Plan Hash: 1134525070 (11 rows)
-
계획의 모든 액세스 방법이 더 이상 사용되지 않습니다.
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Seq Scan on tbl_a1 tbl_a_1 Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50)) SQL Hash: 1553185667, Plan Hash: -694232056 (6 rows)
-
인덱스 방법과 연결된 인덱스가 변경됩니다.
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Seq Scan on tbl_a1 tbl_a_1 Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50)) -> Index Scan using tbl_a2_j_idx on tbl_a2 tbl_a_2 Index Cond: (j < 9910) Filter: ((i >= 990) AND (i <= 1100) AND (k > 50)) SQL Hash: 1553185667, Plan Hash: -993343726 (7 rows)
테이블 파티션 계획 적용
파티셔닝된 테이블에 대한 승인된 계획은 위치 대응과 함께 적용됩니다. 계획은 파티션에만 국한되지 않으며, 원래 쿼리에서 참조된 계획이 아닌 다른 파티션에도 적용할 수 있습니다. 또한 계획에는 원래 승인된 개요와 다른 수의 파티션에 액세스하는 쿼리에 적용할 수 있는 기능이 있습니다.
예를 들어 승인된 개요가 아래 계획에 대한 것이라면 다음과 같습니다.
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1 Index Cond: ((i >= 990) AND (i <= 2100)) Filter: ((j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50)) -> Index Scan using tbl_a3_i_idx on tbl_a3 tbl_a_3 Index Cond: ((i >= 990) AND (i <= 2100)) Filter: ((j < 9910) AND (k > 50)) SQL Hash: 1553185667, Plan Hash: -993736942 (10 rows)
그런 다음 2개, 4개 이상의 파티션을 참조하는 SQL 쿼리에도 이 계획을 적용할 수 있습니다. 2개 및 4개 파티션 액세스에 대한 이러한 시나리오에서 발생할 수 있는 계획은 다음과 같습니다.
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;QUERY PLAN ---------------------------------------------------------------------------------- Append -> Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1 Index Cond: ((i >= 990) AND (i <= 1100)) Filter: ((j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50)) Note: An Approved plan was used instead of the minimum cost plan. SQL Hash: 1553185667, Plan Hash: -993736942, Minimum Cost Plan Hash: -1873216041 (8 rows)
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 3100 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1 Index Cond: ((i >= 990) AND (i <= 3100)) Filter: ((j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50)) -> Index Scan using tbl_a3_i_idx on tbl_a3 tbl_a_3 Index Cond: ((i >= 990) AND (i <= 3100)) Filter: ((j < 9910) AND (k > 50)) -> Seq Scan on tbl_a4 tbl_a_4 Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50)) Note: An Approved plan was used instead of the minimum cost plan. SQL Hash: 1553185667, Plan Hash: -993736942, Minimum Cost Plan Hash: -1873216041 (12 rows)
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 3100 and j < 9910 and k > 50;QUERY PLAN ---------------------------------------------------------------------------------- Append -> Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1 Index Cond: ((i >= 990) AND (i <= 3100)) Filter: ((j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50)) -> Index Scan using tbl_a3_i_idx on tbl_a3 tbl_a_3 Index Cond: ((i >= 990) AND (i <= 3100)) Filter: ((j < 9910) AND (k > 50)) -> Index Scan using tbl_a4_i_idx on tbl_a4 tbl_a_4 Index Cond: ((i >= 990) AND (i <= 3100)) Filter: ((j < 9910) AND (k > 50)) Note: An Approved plan was used instead of the minimum cost plan. SQL Hash: 1553185667, Plan Hash: -993736942, Minimum Cost Plan Hash: -1873216041 (14 rows)
각 파티션마다 다른 액세스 방법을 사용하는 승인된 다른 계획을 고려해 보세요.
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1 Index Cond: ((i >= 990) AND (i <= 2100)) Filter: ((j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50)) -> Bitmap Heap Scan on tbl_a3 tbl_a_3 Recheck Cond: ((i >= 990) AND (i <= 2100)) Filter: ((j < 9910) AND (k > 50)) -> Bitmap Index Scan on tbl_a3_i_idx Index Cond: ((i >= 990) AND (i <= 2100)) SQL Hash: 1553185667, Plan Hash: 2032136998 (12 rows)
이 경우 두 파티션에서 읽어 들이는 계획은 실행되지 않습니다. 승인된 계획의 모든 조합(액세스 방법, 인덱스 이름)을 사용할 수 없으면 계획을 적용할 수 없습니다. 예를 들어 다음 계획에는 서로 다른 계획 해시가 있으며 이러한 경우에는 승인된 계획을 적용할 수 없습니다.
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1900 and j < 9910 and k > 50;QUERY PLAN ------------------------------------------------------------------------- Append -> Bitmap Heap Scan on tbl_a1 tbl_a_1 Recheck Cond: ((i >= 990) AND (i <= 1900)) Filter: ((j < 9910) AND (k > 50)) -> Bitmap Index Scan on tbl_a1_i_idx Index Cond: ((i >= 990) AND (i <= 1900)) -> Bitmap Heap Scan on tbl_a2 tbl_a_2 Recheck Cond: ((i >= 990) AND (i <= 1900)) Filter: ((j < 9910) AND (k > 50)) -> Bitmap Index Scan on tbl_a2_i_idx Index Cond: ((i >= 990) AND (i <= 1900)) Note: This is not an Approved plan. No usable Approved plan was found. SQL Hash: 1553185667, Plan Hash: -568647260 (13 rows)
postgres=>
explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1900 and j < 9910 and k > 50;QUERY PLAN -------------------------------------------------------------------------- Append -> Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1 Index Cond: ((i >= 990) AND (i <= 1900)) Filter: ((j < 9910) AND (k > 50)) -> Seq Scan on tbl_a2 tbl_a_2 Filter: ((i >= 990) AND (i <= 1900) AND (j < 9910) AND (k > 50)) Note: This is not an Approved plan. No usable Approved plan was found. SQL Hash: 1553185667, Plan Hash: -496793743 (8 rows)
이름 지정 규칙
QPM에서 선언적 파티셔닝된 테이블을 사용하여 계획을 적용하려면 상위 테이블, 테이블 파티션 및 인덱스에 대한 특정 이름 지정 규칙을 따라야 합니다.
상위 테이블 이름 - 이 이름은 숫자만이 아니라 알파벳이나 특수 문자로 구분해야 합니다. 예를 들어 tA, tB 및 tC는 개별 상위 테이블에 사용할 수 있는 이름이지만, t1, t2 및 t3는 사용할 수 없습니다.
개별 파티션 테이블 이름 - 동일한 상위 파티션의 파티션은 숫자만 달라야 합니다. 예를 들어 tA의 허용 가능한 파티션 이름은 tA1, tA2 또는 t1A, t2A나 여러 자리 숫자일 수 있습니다.
문자, 특수 문자로 차이를 두면 계획 적용이 보장되지 않습니다.
인덱스 이름 - 파티션 테이블 계층 구조에서 모든 인덱스의 이름이 고유하도록 해야 합니다. 즉, 이름에서 숫자가 아닌 부분이 달라야 합니다. 예를 들어 이름이
tA
인 파티셔닝 테이블에 인덱스 이름이tA_col1_idx1
인 인덱스가 있는 경우 이름이tA_col1_idx2
인 다른 인덱스를 포함할 수 없습니다. 하지만 이름이tA_a_col1_idx2
인 인덱스는 포함할 수 있습니다. 이름에서 숫자가 아닌 부분이 고유하기 때문입니다. 이 규칙은 상위 테이블과 개별 파티션 테이블 모두에 생성된 인덱스에 적용됩니다.
위의 이름 지정 규칙을 준수하지 않을 경우 승인된 계획 적용이 실패할 수 있습니다. 다음은 실패한 적용의 예를 보여줍니다.
postgres=>
create table t1(i int, j int, k int, l int, m int) partition by range(i);CREATE TABLE
postgres=>
create table t1a partition of t1 for values from (0) to (1000);CREATE TABLE
postgres=>
create table t1b partition of t1 for values from (1001) to (2000);CREATE TABLE
postgres=>
SET apg_plan_mgmt.capture_plan_baselines TO 'manual';SET
postgres=>
explain (hashes true, costs false) select count(*) from t1 where i > 0;QUERY PLAN -------------------------------------------------------------------------- Aggregate -> Append -> Seq Scan on t1a t1_1 Filter: (i > 0) -> Seq Scan on t1b t1_2 Filter: (i > 0) SQL Hash: -1720232281, Plan Hash: -1010664377 (7 rows)
postgres=>
SET apg_plan_mgmt.use_plan_baselines TO 'on';SET
postgres=>
explain (hashes true, costs false) select count(*) from t1 where i > 1000;QUERY PLAN ------------------------------------------------------------------------- Aggregate -> Seq Scan on t1b t1 Filter: (i > 1000) Note: This is not an Approved plan. No usable Approved plan was found. SQL Hash: -1720232281, Plan Hash: 335531806 (5 rows)
두 계획이 동일하게 보일 수도 있지만 하위 테이블의 이름 때문에 Plan Hash
값이 다릅니다. 테이블 이름이 숫자만이 아닌 영문자에 따라 다양하므로 적용이 실패합니다.