컬럼 순서 변경 시 기존 저장된 row의 물리적 구조 변화
- Oracle 컬럼 순서 변경과 Row 구조 변화:
기본 원칙: 기존 Row는 변경되지 않음!
- 테스트 데이터 생성 및 ROW 구조 확인
-- 초기 테이블 생성
CREATE TABLE column_order_test (
id NUMBER,
name VARCHAR2(20),
status CHAR(1)
);
-- 초기 데이터 삽입
INSERT INTO column_order_test VALUES (1, 'John', 'A');
INSERT INTO column_order_test VALUES (2, 'Jane', 'B');
COMMIT;
-- 초기 row 구조 확인
SELECT DUMP(id) as id_dump, DUMP(name) as name_dump, DUMP(status) as status_dump
FROM column_order_test WHERE id = 1;
-- Row 구조: [Header][Length: id,name,status][Data: id,name,status]
컬럼 추가 시의 변화
새 컬럼 추가
-- 새 컬럼 추가 (항상 테이블 끝에 추가됨) ALTER TABLE column_order_test ADD (new_col VARCHAR2(10)); -- 기존 데이터 조회 SELECT * FROM column_order_test; -- 결과: id=1, name='John', status='A', new_col=NULL -- id=2, name='Jane', status='B', new_col=NULL
기존 Row vs 새 Row 구조 비교
- 기존 row 구조 (변경되지 않음!)
-- Row 1,2: [Header][Length: id,name,status][Data: id,name,status] -- new_col은 NULL이므로 물리적으로 저장 안됨 -- 새 데이터 삽입 INSERT INTO column_order_test VALUES (3, 'Bob', 'C', 'NEW');
- 새 row 구조
-- Row 3: [Header][Length: id,name,status,new_col][Data: id,name,status,new_col]
- 물리적 구조 확인
SELECT
id,
DUMP(id) as id_dump,
DUMP(name) as name_dump,
DUMP(status) as status_dump,
DUMP(new_col) as new_col_dump
FROM column_order_test;
실제 테스트로 구조 변화 확인
Row 크기 변화 측정
- 테이블 통계 확인
ANALYZE TABLE column_order_test COMPUTE STATISTICS;
SELECT
table_name,
num_rows,
avg_row_len,
blocks
FROM user_tables
WHERE table_name = 'COLUMN_ORDER_TEST';
* Row별 실제 길이 확인 (VSIZE 함수 사용)
<source lang=sql>
SELECT
id,
VSIZE(id) + VSIZE(name) + VSIZE(status) + NVL(VSIZE(new_col),0) + 8 as calc_row_size
FROM column_order_test;
-- +8은 row header + length array 추정치
Block Dump로 물리적 구조 확인
-- ROWID로 물리적 위치 확인 SELECT rowid, id, name, status, new_col FROM column_order_test; -- 결과 예시: -- ROWID ID NAME STATUS NEW_COL -- -------------------- --- ----- ------ ------- -- AAAEGkAABAAAQCYAAA 1 John A [NULL] ← 기존 구조 유지 -- AAAEGkAABAAAQCYAAB 2 Jane B [NULL] ← 기존 구조 유지 -- AAAEGkAABAAAQCYAAC 3 Bob C NEW ← 새 구조 ```
컬럼 순서 변경의 실제 방법들
테이블 재생성 방법 (CTAS)
-- 1. 새 순서로 테이블 재생성
CREATE TABLE column_order_test_new AS
SELECT
id, -- 1번째
new_col, -- 2번째 (순서 변경!)
name, -- 3번째
status -- 4번째
FROM column_order_test;
-- 2. 기존 테이블 삭제하고 이름 변경
DROP TABLE column_order_test;
RENAME column_order_test_new TO column_order_test;
-- 3. 모든 row가 새 구조로 저장됨
-- 새 Row 구조: [Header][Length: id,new_col,name,status][Data: id,new_col,name,status]
DBMS_REDEFINITION 사용
-- Online 테이블 재정의 (운영 중에도 가능)
BEGIN
-- 재정의 시작
DBMS_REDEFINITION.START_REDEF_TABLE(
uname => USER,
orig_table => 'COLUMN_ORDER_TEST',
int_table => 'COLUMN_ORDER_TEST_NEW'
);
-- 재정의 완료
DBMS_REDEFINITION.FINISH_REDEF_TABLE(
uname => USER,
orig_table => 'COLUMN_ORDER_TEST',
int_table => 'COLUMN_ORDER_TEST_NEW'
);
END;
/
Update 시 Row 구조 변화
기존 Row의 Update 동작
-- 기존 row에 새 컬럼 값 할당 UPDATE column_order_test SET new_col = 'UPDATED' WHERE id = 1; -- Update 후 row 구조: -- Before: [Header][Length: id,name,status][Data: id,name,status] -- After: [Header][Length: id,name,status,new_col][Data: id,name,status,new_col] -- 주의: Row 크기 증가로 인한 Row Migration 가능성!
Row Migration 확인
-- Row migration 발생 확인
SELECT
table_name,
num_rows,
chain_cnt,
(chain_cnt/num_rows)*100 as migration_pct
FROM user_tables
WHERE table_name = 'COLUMN_ORDER_TEST';
-- Migration된 row 확인
ANALYZE TABLE column_order_test LIST CHAINED ROWS;
혼재된 Row 구조의 성능 영향
같은 테이블 내 다른 구조들
-- 혼재 상황 예시: -- Row 1,2: [id][name][status] (old structure) -- Row 3: [id][name][status][new_col] (new structure) -- Row 1*: [id][name][status][new_col] (updated old row) -- 성능 측정 SET AUTOTRACE ON STATISTICS -- 전체 스캔 시 다양한 row 구조 처리 비용 SELECT COUNT(*) FROM column_order_test WHERE new_col IS NOT NULL; SELECT COUNT(*) FROM column_order_test WHERE name LIKE 'J%';
컬럼 접근 패턴 차이
-- 구조가 다른 row들의 컬럼 접근 비용
SELECT
id,
CASE
WHEN new_col IS NULL THEN 'Old Structure'
ELSE 'New Structure'
END as row_type,
name,
status,
new_col
FROM column_order_test;
-- 실행계획에서 consistent gets 비교
실무 관점에서의 권장사항
컬럼 순서 변경 시나리오
- 방법 1: 테이블 재생성 (완전한 구조 통일)
CREATE TABLE new_table AS SELECT col1, col3, col2, col4 FROM old_table; -- 원하는 순서
- 방법 2: 점진적 마이그레이션
-- 1단계: 새 컬럼 추가 -- 2단계: 데이터 이관 -- 3단계: 기존 컬럼 삭제 -- 4단계: 컬럼 이름 변경
- 방법 3: View로 논리적 순서 변경
CREATE VIEW logical_order_view AS SELECT col1, col3, col2, col4 FROM physical_table;
성능 모니터링
-- 혼재된 구조의 성능 영향 확인
SELECT sql_id,
executions,
buffer_gets,
disk_reads,
elapsed_time/1000000 as elapsed_sec
FROM v$sql
WHERE sql_text LIKE '%COLUMN_ORDER_TEST%'
ORDER BY buffer_gets DESC;
vpn_key 컬럼 순서가 변경 되면 row가 저장된 데이터 블럭 전체가 변경이 될까?
playlist_add_check[요점정리]
- 1) 컬럼 순서 변경 시 Row 구조 변화
- 기존 Row: 물리적 구조 변경되지 않음(그대로 유지)
- 새 Row추가시 : 새로운 컬럼 순서로 저장**
- Updated Row: 새 구조로 재작성(Row Migration 가능)
- 혼재 상황**: 같은 테이블에 다른 구조의 row들이 공존
- 1) 컬럼 순서 변경 시 Row 구조 변화
- 2) 성능 영향
- Full Table Scan: 다양한 구조 처리로 약간의 오버헤드
- Index Scan: 큰 영향 없음
- Update 연산: Row Migration 위험
- 메모리 사용: Row 구조 다양성으로 캐시 효율성 약간 저하
- 2) 성능 영향
- 3) 실무 권장 사항 :
- 컬럼 순서 변경 시 테이블 재생성 고려
- 점진적 마이그레이션 계획 수립
- 성능 테스트 필수
- Row Migration 모니터링 지속
- 3) 실무 권장 사항 :