⭐ 먼저 알아야 할 핵심 개념
대량 적재(Bulk Insert)는 데이터를 한 행씩 저장하지 않고 여러 행을 묶어서 DB에 저장하는 방식이다.
한 행씩 INSERT하면 DB에 계속 요청을 보내야 하므로 데이터가 많을수록 비효율적이다. 따라서 여러 데이터를 묶어서 보내 DB와의 왕복 횟수를 줄이는 것이 핵심이다.
90,000행
1행씩 전송 → 최대 90,000번의 실행/요청 ❌
5,000행씩 묶기 → 훨씬 적은 횟수로 처리 ⭕
대량 적재 방법
1. execute() 반복
- 한 행씩 SQL을 실행하므로 대량 적재에 비효율적일 수 있다.
- 가장 느리다.
2. executemany()
- 같은 SQL에 여러 데이터를 전달해 처리한다.
3. to_sql()
- DataFrame을 DB 테이블에 바로 저장한다. -> 내부적으로는 executemany를 사용한다.
- 직접 insert문을 작성하지 않아도 된다.
- if_exists : "append"(뒤에 붙임) / "replace"(테이블 지우고 새로만듬) / "fail"(실패처리)
4. to_sql(method="multi")
- 여원하는 개수만큼 청킹해서 INSERT시킬 수 있다.
df.to_sql(
"daily_price",
engine,
if_exists="append",
method="multi",
chunksize=5000
)
대량 데이터는 한 행씩 처리하기보다 여러 행을 묶어서 처리하는 것이 일반적으로 효율적이다.
⭐ DB 왕복 비용
왕복 비용(Round Trip Cost)은 프로그램이 DB에 요청을 보내고 응답을 받는 데 드는 비용이다.
DB가 같은 컴퓨터에 있으면 왕복 비용이 작아서 차이를 체감하기 어려울 수 있다.
하지만 실무에서는 애플리케이션과 DB가 다른 서버에 있는 경우가 많아 네트워크 비용이 추가된다.
Application
↓ 요청
DB
↓ 응답
Application
이 작업이 수만 번 반복되면 시간이 누적되므로 가능하면 여러 데이터를 묶어서 요청 횟수를 줄인다.
⭐ Chunking과 chunksize
Chunking은 대량 데이터를 일정한 크기로 나누어 처리하는 방식이며, chunksize는 한 번에 처리할 행의 개수다.
예를 들어 90,000행을 chunksize=5000으로 처리하면 데이터를 5,000행 단위로 나누어 적재한다.
왜 그냥 90,000행을 한꺼번에 보내지 않을까?
너무 작게 묶음
→ 왕복 횟수 증가
적당하게 묶음
→ 왕복 횟수와 처리 부담의 균형
너무 크게 묶음
→ 메모리·SQL 크기·트랜잭션 부담 증가
따라서 chunksize=5000 같은 값은 절대적인 정답이 아니라 환경에 따라 테스트해서 결정해야 한다.
max_allowed_packet
max_allowed_packet은 MySQL이 한 번에 주고받을 수 있는 패킷의 최대 크기다.
너무 많은 데이터를 하나의 요청으로 묶으면 이 제한을 초과하여 오류가 발생할 수 있다.
이런 경우 한 번에 보내는 데이터가 작아지도록 chunksize를 줄일 수 있다.
한 번에 너무 많은 데이터
↓
max_allowed_packet 초과 가능
↓
chunksize ↓
↓
여러 번 나누어 전송
⭐ 인덱스와 INSERT 성능
인덱스는 조회를 빠르게 해주지만, INSERT할 때 인덱스도 갱신해야 하므로 적재 비용이 증가할 수 있다.
데이터 하나가 추가되면 DB는 데이터만 저장하는 것이 아니라 관련 인덱스도 관리해야 한다.
INSERT
├─ 데이터 저장
└─ 인덱스 갱신
따라서 인덱스가 많을수록 대량 적재가 느려질 수 있다.
UNIQUE(code, date)
하지만 중복 방지를 위해 필요한 제약조건은 단순히 속도를 높이기 위해 제거하면 안 된다.
이건 속도를 위한게 아니라 중복 차단을 위한 것. 목적이 다르다~
참고: itertuples()
for row in df.itertuples(index=False):
...
DataFrame을 반드시 행 단위로 반복해야 한다면 iterrows()보다 일반적으로 itertuples()가 빠르다.
다만 대량 DB 적재에서는 행 반복 자체를 줄이고 executemany()나 to_sql()처럼 묶어서 처리하는 방법을 우선 고려하는 것이 좋다.
최종 정리
| 개념 | 핵심 |
| Bulk Insert | 여러 행을 묶어서 DB에 저장 |
| 왕복 비용 | DB 요청·응답이 반복되면서 발생하는 비용 |
| executemany() | 같은 SQL로 여러 데이터를 처리 |
| to_sql() | DataFrame을 DB에 직접 저장 |
| Chunking | 대량 데이터를 일정 크기로 나누어 처리 |
| chunksize | 한 번에 처리할 행 개수 |
| max_allowed_packet | MySQL의 한 번에 주고받을 수 있는 패킷 크기 제한 |
| 인덱스 | 조회는 빨라지지만 INSERT 시 갱신 비용 발생 |
⭐ 대량 데이터는 한 행씩 보내지 말고 묶어서 보낸다.
다만 무조건 크게 묶는 것이 좋은 것은 아니다.
너무 작으면 DB 왕복이 많아지고, 너무 크면 메모리·트랜잭션·전송 크기의 부담이 커지므로 Chunking을 이용해 적절한 크기로 나누는 것이 핵심이다.
'- > Pandas' 카테고리의 다른 글
| Pandas: 멱등성과 UPSERT (0) | 2026.09.03 |
|---|---|
| Pandas: 원본 데이터와 정제 데이터의 스키마 설계 (0) | 2026.09.03 |
| Pandas와 DB 연동 + DB 작업 시 조심할 점 3가지 (0) | 2026.09.03 |
| Pandas: DataFrame 결합(Merge) 기본 및 키 정 (0) | 2026.08.30 |
| Pandas: 데이터 결측 처리 전략 및 시계열 보간 (0) | 2026.08.30 |