목록으로

Programming Notes

Oracle 대용량 테이블, Parquet으로 이사 가자! – ORA_HASH & 멀티프로세싱 활용기

Oracle 데이터베이스에 덩치 큰 테이블, 하나쯤은 가지고 계시죠? 그 테이블, 분석이나 머신러닝에 활용하려고 보니 여간 번거로운 게 아닙니다. 매번 쿼리 날리기도 힘들고, 데이터 추출 시간도 너무 오래 걸리고... 이럴 때 Parquet 파일 포맷으로 변환하면 쿼리 성능은...

Oracle 데이터베이스에 덩치 큰 테이블, 하나쯤은 가지고 계시죠? 그 테이블, 분석이나 머신러닝에 활용하려고 보니 여간 번거로운 게 아닙니다. 매번 쿼리 날리기도 힘들고, 데이터 추출 시간도 너무 오래 걸리고... 이럴 때 Parquet 파일 포맷으로 변환하면 쿼리 성능은 물론 스토리지 효율까지 잡을 수 있습니다. 하지만 대용량 테이블을 그냥 변환하면 시간이 너무 오래 걸리죠. 그래서 준비했습니다. ORA_HASH 함수와 Python 멀티프로세싱을 활용해서 효율적으로 변환하는 방법을 소개합니다.

대용량 데이터, 똑똑하게 나누고 빠르게 처리하기

핵심은 데이터를 잘게 쪼개서 병렬로 처리하는 겁니다. Oracle의 ORA_HASH 함수를 사용하면 특정 컬럼 값을 기준으로 데이터를 균등하게 나눌 수 있습니다. 예를 들어, SYS.DEPENDENCY$ 테이블의 D_OBJ# || P_OBJ# 컬럼을 기준으로 ORA_HASH를 적용하고, 해시 값을 10으로 나눈 나머지를 기준으로 10개의 그룹으로 분리하는 것이죠.

이제 분리된 데이터를 Python 멀티프로세싱으로 동시에 처리합니다. 먼저 cx_Oracle 라이브러리를 사용해서 Oracle 데이터베이스에 연결하고, 각 그룹에 해당하는 데이터를 추출하는 SQL 쿼리를 작성합니다. 예를 들어, 특정 그룹(예: 그룹 0)에 해당하는 데이터를 추출하는 쿼리는 다음과 같은 형태가 될 수 있습니다.

SELECT *
FROM SYS.DEPENDENCY$
WHERE MOD(ORA_HASH("D_OBJ# || P_OBJ#", 9), 10) = 0;

이 쿼리를 각 그룹별로 실행하는 함수를 만들고, Python의 multiprocessing 모듈을 사용해서 여러 개의 프로세스를 실행하여 각 그룹의 데이터를 병렬로 추출합니다. 추출된 데이터는 pandas DataFrame으로 변환하고, pyarrow 라이브러리를 사용하여 Parquet 파일로 저장합니다. 이때, 각 프로세스는 서로 다른 그룹의 데이터를 처리하므로, 전체 변환 시간을 획기적으로 단축할 수 있습니다.

예를 들어, 4개의 프로세스를 사용한다면, 데이터 추출 및 변환 시간을 이론적으로는 1/4로 줄일 수 있습니다. (물론, CPU 코어 수, 디스크 I/O, 네트워크 상황 등에 따라 실제 성능은 달라질 수 있습니다.) 코드를 짤 때 주의할 점은, 데이터베이스 연결은 각 프로세스 내에서 독립적으로 생성해야 한다는 것입니다. 메인 프로세스에서 생성된 연결을 자식 프로세스에 공유하면 예기치 않은 오류가 발생할 수 있습니다.

효율적인 데이터 변환, 그 이상의 가치

ORA_HASH와 멀티프로세싱을 활용한 Parquet 변환은 단순히 파일 포맷을 바꾸는 것 이상의 가치를 제공합니다.

  • 쿼리 성능 향상: Parquet 파일은 컬럼 기반 포맷이므로, 필요한 컬럼만 읽어오는 것이 가능합니다. 이는 전체 데이터를 읽어오는 것에 비해 훨씬 빠릅니다.
  • 스토리지 효율성 증대: Parquet 파일은 데이터 압축 효율이 높기 때문에, Oracle 테이블에 비해 저장 공간을 절약할 수 있습니다.
  • 분석 및 머신러닝 활용 용이: Parquet 파일은 Spark, Dask 등 다양한 데이터 분석 플랫폼과 호환되므로, 데이터를 쉽게 활용할 수 있습니다.

이제 덩치 큰 Oracle 테이블 때문에 더 이상 고민하지 마세요. ORA_HASH와 Python 멀티프로세싱을 활용해서 효율적으로 Parquet 파일로 변환하고, 데이터 분석 능력을 한 단계 업그레이드해 보세요!