2026년 09월 21일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-14038 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-14038 GLOBAL partitioned index must be prefixed 는?
ORA-14038 에러는 Oracle 데이터베이스에서 GLOBAL 파티션 인덱스를 생성할 때, 해당 인덱스가 반드시 “Prefixed” 형태여야 한다는 제약 조건을 위반했을 때 발생합니다. Prefixed 인덱스란 인덱스의 첫 번째 컬럼이 파티션 키의 첫 번째 컬럼과 동일한 인덱스를 의미하며, GLOBAL 파티션 인덱스에서는 이 규칙이 필수적으로 적용됩니다. 이 에러는 주로 대용량 테이블의 인덱스 설계 과정이나 기존 인덱스를 파티션 인덱스로 변경하려는 작업 중에 자주 발생하며, 잘못된 파티션 키 또는 인덱스 컬럼 순서 설정이 주된 원인입니다.
주요 발생 원인
1. GLOBAL 파티션 인덱스의 파티션 키가 인덱스 선두 컬럼과 불일치
GLOBAL 파티션 인덱스를 생성할 때 PARTITION BY 절에 지정한 컬럼이 인덱스를 구성하는 첫 번째 컬럼과 다를 경우 이 에러가 발생합니다. 예를 들어 인덱스가 (DEPT_ID, EMP_ID) 순서로 구성되어 있는데, PARTITION BY 절에 EMP_ID를 파티션 키로 지정하면 Oracle은 이를 Non-Prefixed로 판단하고 에러를 반환합니다. GLOBAL 파티션 인덱스는 Prefixed 구조만 허용하기 때문에, 파티션 키는 반드시 인덱스의 선두 컬럼으로 지정되어야 합니다.
2. Non-Prefixed GLOBAL 인덱스 생성 시도
Oracle에서는 LOCAL 파티션 인덱스는 Non-Prefixed 형태를 허용하지만, GLOBAL 파티션 인덱스는 Non-Prefixed 형태를 지원하지 않습니다. 이 차이를 혼동하여 GLOBAL 키워드와 함께 Non-Prefixed 구조의 인덱스를 생성하려고 하면 반드시 ORA-14038이 발생합니다. DBA나 개발자가 LOCAL과 GLOBAL 파티션 인덱스의 특성을 정확히 이해하지 못한 채 인덱스를 설계할 때 특히 많이 발생하는 원인입니다.
3. 복합 인덱스에서 파티션 키 컬럼 순서 오류
복합 인덱스(Composite Index)를 GLOBAL 파티션 인덱스로 생성할 때, 파티션 키로 사용할 컬럼이 인덱스 컬럼 목록의 두 번째 이후에 위치하는 경우에도 이 에러가 발생합니다. 예를 들어 인덱스를 (ORDER_DATE, ORDER_ID, CUSTOMER_ID)로 구성하면서 PARTITION BY (ORDER_ID)를 지정하면, ORDER_ID가 선두 컬럼이 아니므로 Non-Prefixed로 간주되어 에러가 발생합니다. 복합 인덱스 설계 시 파티션 키를 반드시 선두 컬럼으로 배치해야 한다는 점을 간과하기 쉬운 실수입니다.
해결 방법
해결책 1: 파티션 키를 인덱스 선두 컬럼으로 변경
가장 근본적인 해결 방법은 인덱스 컬럼 순서를 재조정하여 파티션 키가 선두 컬럼이 되도록 변경하는 것입니다.
에러 발생 예제:
-- 아래 구문은 ORA-14038 에러 발생
CREATE INDEX idx_emp_global
ON employees(dept_id, emp_id)
GLOBAL PARTITION BY RANGE (emp_id)
(
PARTITION p1 VALUES LESS THAN (1000),
PARTITION p2 VALUES LESS THAN (2000),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
해결된 예제 (파티션 키를 선두 컬럼으로 이동):
-- emp_id를 선두 컬럼으로 변경하여 Prefixed 구조 적용
CREATE INDEX idx_emp_global
ON employees(emp_id, dept_id)
GLOBAL PARTITION BY RANGE (emp_id)
(
PARTITION p1 VALUES LESS THAN (1000),
PARTITION p2 VALUES LESS THAN (2000),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
해결책 2: GLOBAL 대신 LOCAL 파티션 인덱스로 변경
Non-Prefixed 구조가 반드시 필요한 경우라면 GLOBAL 대신 LOCAL 파티션 인덱스를 사용하는 것을 검토해야 합니다. LOCAL 파티션 인덱스는 Non-Prefixed 형태를 허용합니다.
-- LOCAL 파티션 인덱스는 Non-Prefixed 허용
-- 단, 테이블이 파티션 테이블이어야 함
CREATE INDEX idx_emp_local
ON employees(dept_id, emp_id)
LOCAL;
-- LOCAL 파티션 인덱스 생성 확인
SELECT index_name, partitioning_type, locality, alignment
FROM dba_part_indexes
WHERE table_name = 'EMPLOYEES';
해결책 3: 복합 인덱스의 컬럼 순서 재정렬
복합 GLOBAL 파티션 인덱스에서 파티션 키 컬럼이 선두에 위치하도록 인덱스를 재생성합니다.
-- 에러 발생: ORDER_ID가 선두 컬럼이 아님
CREATE INDEX idx_order_global
ON orders(order_date, order_id, customer_id)
GLOBAL PARTITION BY RANGE (order_id)
(
PARTITION p1 VALUES LESS THAN (10000),
PARTITION p2 VALUES LESS THAN (20000),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
-- 해결: ORDER_ID를 선두 컬럼으로 배치
CREATE INDEX idx_order_global
ON orders(order_id, order_date, customer_id)
GLOBAL PARTITION BY RANGE (order_id)
(
PARTITION p1 VALUES LESS THAN (10000),
PARTITION p2 VALUES LESS THAN (20000),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
해결책 4: 기존 인덱스 확인 및 재생성 스크립트
운영 중인 시스템에서 문제가 되는 인덱스를 찾고 재생성하는 절차입니다.
-- 현재 파티션 인덱스 정보 조회
SELECT pi.index_name,
pi.table_name,
pi.partitioning_type,
pi.locality,
pi.alignment
FROM dba_part_indexes pi
WHERE pi.table_name = 'YOUR_TABLE_NAME'
ORDER BY pi.index_name;
-- 인덱스 컬럼 구성 확인
SELECT ic.index_name,
ic.column_name,
ic.column_position
FROM dba_ind_columns ic
WHERE ic.table_name = 'YOUR_TABLE_NAME'
ORDER BY ic.index_name, ic.column_position;
-- 인덱스 파티션 키 확인
SELECT name, column_name, column_position
FROM dba_part_key_columns
WHERE name IN (
SELECT index_name
FROM dba_part_indexes
WHERE table_name = 'YOUR_TABLE_NAME'
);
-- 기존 인덱스 삭제 후 올바른 순서로 재생성
DROP INDEX idx_emp_global;
CREATE INDEX idx_emp_global
ON employees(emp_id, dept_id, hire_date)
GLOBAL PARTITION BY RANGE (emp_id)
(
PARTITION p_low VALUES LESS THAN (1000),
PARTITION p_mid VALUES LESS THAN (5000),
PARTITION p_high VALUES LESS THAN (MAXVALUE)
);
예방 방법
1. 인덱스 설계 단계에서 GLOBAL/LOCAL 파티션 특성 문서화 및 검토
GLOBAL 파티션 인덱스를 생성하기 전에 인덱스 컬럼 목록과 파티션 키를 반드시 사전 검토하는 절차를 표준으로 정립해야 합니다. 팀 내에서 인덱스 설계 가이드라인을 문서화하고, “GLOBAL 파티션 인덱스는 반드시 Prefixed여야 한다”는 규칙을 설계 체크리스트에 포함시켜 코드 리뷰 단계에서 사전 차단하는 것이 효과적입니다. 특히 신규 개발자나 파티셔닝 경험이 부족한 담당자에게는 LOCAL과 GLOBAL 파티션 인덱스의 차이를 교육하고, 인덱스 생성 스크립트를 반드시 DBA 검토 후 적용하는 절차를 도입하는 것이 좋습니다.
2. 개발/스테이징 환경에서 인덱스 생성 스크립트 사전 검증
운영 환경에 반영하기 전, 동일한 구조의 개발 또는 스테이징 환경에서 파티션 인덱스 생성 스크립트를 반드시 사전 실행하여 에러 여부를 확인하는 프로세스를 수립해야 합니다. 아래와 같이 인덱스 생성 전 파티션 키와 인덱스 선두 컬럼의 일치 여부를 자동으로 검증하는 스크립트를 활용하면 실수를 크게 줄일 수 있습니다.
-- GLOBAL 파티션 인덱스의 Alignment 사전 확인 쿼리
-- PREFIXED가 아닌 경우 생성 전 수정 필요
SELECT pi.index_name,
pi.table_name,
pi.locality,
pi.alignment,
CASE
WHEN pi.locality = 'GLOBAL' AND pi.alignment != 'PREFIXED'
THEN '⚠️ ORA-14038 위험: GLOBAL 인덱스가 NON-PREFIXED입니다'
ELSE '✅ 정상'
END AS check_result
FROM dba_part_indexes pi
WHERE pi.owner = 'YOUR_SCHEMA'
ORDER BY pi.table_name, pi.index_name;
관련 에러
- ORA-14037: LOCAL 파티션 인덱스가 Prefixed 구조를 위반했을 때 발생하는 에러로, ORA-14038과 쌍을 이루는 에러입니다. LOCAL 파티션 인덱스는 Non-Prefixed를 허용하지만, 특정 조건에서 Prefixed 제약이 적용될 수 있습니다.
- ORA-14036: 파티션 인덱스의 파티션 경계값이 파티션 키 컬럼 수보다 많을 때 발생하는 에러입니다.
- ORA-14016: LOCAL 파티션 인덱스에서 파티션 키가 잘못 지정되었을 때 발생합니다. GLOBAL과 LOCAL의 파티셔닝 규칙 차이에서 비롯된 관련 에러군에 속합니다.
- ORA-14501: 파티션 인덱스 또는 테이블이 UNUSABLE 상태일 때 발생하며, 잘못된 인덱스 재생성 작업 후 연쇄적으로 발생할 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.