메인 콘텐츠로 건너뛰기

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
행을 하나씩 삽입하는 것은 대량 가져오기를 느리게 만드는 가장 빠른 방법입니다. MySQL은 각 단일 행 INSERT를 완전한 트랜잭션 커밋으로 처리합니다 — 파싱, 계획, 실행, fsync. 규모가 커지면 행당 오버헤드가 지배적이 됩니다. 이를 피하는 방법은 다음과 같습니다.

다중 행 INSERT

가장 간단한 최적화: 여러 행을 하나의 문으로 묶습니다.
배치 크기가 중요합니다. 문당 수백에서 수천 행이 보통 최적입니다 — 더 큰 배치는 메모리 압박을 높이고 트랜잭션 지속 시간을 늘립니다. 워크로드에 맞는 최적점을 찾으려면 벤치마크하세요. 배치당 500–2000행이 일반적인 시작점입니다.

트랜잭션 배치 처리

많은 INSERT를 하나의 트랜잭션으로 감싸면 문마다 발생하는 커밋 오버헤드를 피할 수 있습니다:
명시적 트랜잭션이 없으면 각 INSERT는 자동 커밋됩니다. 자동 커밋은 각 행이 개별적으로 디스크에 플러시된다는 뜻입니다. 500개의 삽입을 하나의 트랜잭션으로 감싸면 플러시는 한 번만 일어납니다. 이를 다중 행 INSERT와 결합하세요: 문당 500–1000행 단위로 행을 묶고, 각 배치를 트랜잭션으로 감쌉니다.

LOAD DATA INFILE

큰 CSV 가져오기에는 LOAD DATA INFILE이 가장 빠른 MySQL 네이티브 옵션입니다 — 행마다 SQL 파싱을 거치지 않으므로 배치 INSERT보다 훨씬 빠릅니다.
파일은 MySQL 서버 프로세스가 읽을 수 있어야 합니다. 기본적으로 파일 경로는 secure_file_priv로 지정된 디렉토리로 제한됩니다:
서버가 아닌 클라이언트 머신에서 파일을 로드하려면:
LOCAL INFILE은 서버에서 local_infile = ON이 설정되어 있어야 하고, 클라이언트에서 --local-infile 플래그가 활성화되어 있어야 합니다.

INSERT … SELECT

테이블 간 데이터 복사(ETL 패턴, 스테이징 테이블)에는 INSERT...SELECT가 행을 애플리케이션으로 읽어 들여 다시 삽입하는 것보다 빠릅니다:

대량 로드 중 인덱스 비활성화

MyISAM 테이블에서는 대량 삽입 중 비고유 인덱스 업데이트를 비활성화하면 속도가 크게 빨라집니다:
InnoDB에서는 같은 효과가 없습니다. 대신 InnoDB는 보조 인덱스 업데이트에 “체인지 버퍼”를 자동으로 사용합니다. InnoDB 대량 로드 성능을 최대화하려면:
로드가 끝나면 즉시 다시 활성화하세요. 실제로 중복이 있는 데이터에서 unique_checks를 비활성화하면 손상된 인덱스가 만들어집니다.

성능 비교

정확한 수치는 행 크기, 인덱스, 하드웨어, 구성에 따라 크게 달라집니다. 각자의 경우를 벤치마크하세요.

자주 묻는 질문

각 INSERT 배치는 얼마나 커야 하나요?

500–1000행에서 시작하여 벤치마크하세요. 더 큰 배치는 커밋당 오버헤드를 줄이지만 메모리 사용량과 트랜잭션 지속 시간(잠금을 더 오래 유지)을 늘립니다. 배치가 실패하면 배치 전체가 롤백됩니다 — 더 작은 배치는 롤백 작업이 적다는 뜻입니다. 대부분의 애플리케이션에서 최적 배치 크기는 500에서 5000행 사이입니다.

LOAD DATA INFILE을 ON DUPLICATE KEY UPDATE와 함께 사용할 수 있나요?

LOAD DATA는 중복 처리를 위해 REPLACE 또는 IGNORE를 지원하지만 ON DUPLICATE KEY UPDATE는 지원하지 않습니다. 대량 로드 중 업서트 동작이 필요하다면 스테이징 테이블에 로드한 다음, 스테이징 테이블에서 대상 테이블로 INSERT...SELECT...ON DUPLICATE KEY UPDATE를 사용하세요.

대량 삽입은 트리거를 우회하나요?

아니요. 트리거는 LOAD DATA INFILE과 INSERT...SELECT로 로드된 행을 포함하여 영향을 받는 모든 행에 대해 실행됩니다. 트리거가 많은 작업을 수행한다면 대량 로드가 그에 비례하여 느려집니다. 순수한 데이터 마이그레이션에서는 트리거를 일시적으로 비활성화하는 것이 좋을 수 있습니다.

문제 해결

이 로딩 기법들은 MySQL의 드롭인 대체품이자 확장 기능을 갖춘 VillageSQL에서도 변경 없이 동작합니다.

참고