- 공유 링크 만들기
- X
- 이메일
- 기타 앱
이 글의 목적은 수십만 행 이상의 대용량 엑셀 파일에서 발생하는 느려짐 문제를 구조적으로 진단하고, 계산·메모리·입출력 병목을 제거하여 체감 속도를 최대화하는 실무 최적화 방법을 제공하는 것이다.
1. 대용량 파일이 느려지는 근본 원리
엑셀 성능은 크게 계산 엔진, 메모리 사용량, 디스크 입출력, UI 렌더링 네 요소에 의해 좌우되며, 각 요소는 수식 개수와 복잡도, 피벗 캐시와 데이터 모델의 크기, 통합문서 내 개체 수, 조건부서식 규칙 수, 외부연결·실시간 기능 사용 여부 등에 의해 증폭됨에 따라 기하급수적으로 느려지는 경향이 있다. 특히 전체 열 참조, 휘발성 함수, 과도한 배열 수식, 중첩된 참조 체인은 계산 그래프의 폭과 깊이를 동시에 키워 재계산 비용을 크게 증가시키는 특성이 있다.
2. 10분 만에 끝내는 속도 점검 체크리스트
| 항목 | 권장 설정/행동 | 효과 | 리스크 |
|---|---|---|---|
| 계산 모드 | 수동 계산, 저장 전 F9 또는 시트별 계산 | 대폭 | 값 최신화 누락 주의 |
| 저장 형식 | .xlsx → .xlsb 저장 | 용량·저장속도 개선 | 외부도구 호환성 |
| 휘발성 함수 제거 | OFFSET, INDIRECT, TODAY 등 대체 | 재계산 감소 | 기능 대체 설계 필요 |
| 전체열 참조 제거 | A:A 대신 A$2:A$500000 범위 | 계산 범위 축소 | 범위 유지 관리 |
| 조건부서식 정리 | 중복 규칙 병합, 범위 최소화 | 렌더링·계산 개선 | 시각 규칙 단순화 |
| 테이블 사용 | 데이터를 표(CTRL+T)로 구조화 | 증분 계산, 가독성 | 구조 참조 적응 필요 |
| Power Query | 가공은 PQ로, 시트 수식 최소화 | 메모리·속도 개선 | 초기 학습 필요 |
| 피벗 캐시 | 공유 캐시, 필요 없는 캐시 삭제 | 메모리 절감 | 피벗 재설정 가능성 |
| 이미지·개체 | 불필요 개체 일괄 삭제 | UI·파일 크기 개선 | 시각자료 손실 |
| 하드웨어 | 64비트 엑셀, RAM 16GB 이상 | 대용량 안정성 | 환경 변경 필요 |
3. 저장 형식과 파일 구조 최적화
.xlsb(바이너리 통합문서)로 저장하면 압축 효율과 저장·열기 속도가 개선되는 경향이 있다. 특히 여러 시트, 피벗, 조건부서식이 많은 파일에서 효과가 체감된다. 또한 사용하지 않는 시트, 숨겨진 이름정의, 깨진 연결, 버려진 피벗 캐시는 파일 부풀리기와 느려짐의 대표 요인이므로 정리해야 한다.
3.1 숨겨진 이름정의와 깨진 참조 정리
수식 > 이름 관리자 - #REF! 포함 이름 삭제 또는 참조 재지정 - 범위가 전체 열인 이름은 끝행까지 고정(A$2:A$500000)으로 축소 - 외부 통합문서 참조([Book.xlsx]Sheet!A1) 불필요 시 제거
3.2 불필요 개체 대량 삭제
F5(이동) > 셀 선택 > 개체 Delete 키로 불필요 도형/이미지/차트 삭제
4. 계산 엔진 최적화: 함수·수식 설계 원칙
4.1 휘발성 함수 최소화
OFFSET, INDIRECT, TODAY, RAND, NOW, CELL, INFO 등은 통합문서 변경 시마다 재계산되어 큰 비용이 발생한다. 동적 참조는 INDEX로 대체하고, 날짜는 입력 파라미터 셀을 사용하여 값 변화를 통제한다.
-- 나쁜 예 =SUM(OFFSET(A1,0,0,COUNTA(A:A),1))
-- 권장 대체
=SUM(A1:INDEX(A:A, MATCH("Ω", A:A))) '종단 마커 사용
4.2 전체 열 참조 회피
수십만 행 데이터에서 A:A 같은 전체 열 참조는 쿼리 범위를 불필요하게 확대한다. 데이터 끝행을 동적으로 관리하되 명확한 상한을 지정한다.
=SUMIFS($D$2:$D$500000,$A$2:$A$500000,H2,$B$2:$B$500000,I2)
4.3 조회 함수 선택 전략
VLOOKUP의 첫 열 고정 제약과 열 삽입 취약성을 회피하려면 INDEX/MATCH 또는 XLOOKUP을 사용한다. 다만 대량 조회 시 다중 MATCH 중복 계산을 피하기 위해 키 컬럼에 보조열을 도입하거나 LET·LAMBDA로 캐시한다.
-- XLOOKUP 기본 =XLOOKUP(Key, KeyRange, ValueRange, "없음",
0)
-- INDEX/MATCH 조합
=INDEX(ValueRange, MATCH(Key, KeyRange,
0))
-- 중복 MATCH 캐시(LET)
=LET(k, A2, r, MATCH(k, KeyRange,
0), INDEX(ValueRange, r))
4.4 배열 수식과 동적 배열 관리
필요 이상의 스필 범위를 방지하고, FILTER·UNIQUE의 입력 범위를 표 객체로 제한하여 계산량을 축소한다. 다단 필터는 Power Query로 위임하는 편이 더 빠르다.
4.5 사용자 정의 함수(UDF) 최소화
VBA UDF는 네이티브 함수보다 느린 경우가 많다. 동일 로직이 워크시트 함수나 Power Query, Power Pivot로 대체 가능하면 변경한다.
5. 조건부서식과 서식 범위 최적화
조건부서식은 셀 렌더링과 계산 모두에 부담이 된다. 규칙을 통합하고 범위를 실제 데이터 영역으로 제한한다. 동일 규칙이 시트에 중복되어 있으면 관리자에서 정렬·중복 제거를 실행한다. 셀 서식은 최소한으로 유지하고, 수천 개의 개별 서식 대신 표 스타일을 적용한다.
6. Power Query로 데이터 가공 오프로딩
대규모 정제·조인·피벗/언피벗은 Power Query에서 수행하고 결과만 시트에 적재하는 것이 효율적이다. 쿼리 설정에서 로드 대상은 테이블 또는 데이터 모델 중 하나로 제한하고, 중복 로드는 피한다. 단계는 필요한 만큼만 유지하며, 형 변환은 초기 단계에서 명확히 지정한다.
Power Query 성능 팁 - 중간 단계 결과 '사용 안 함'으로 설정하여 불필요 캐시 배제 - 병합 전 키 컬럼 정렬 및 중복 제거나 인덱스 부여 - 형식 지정은 일괄 적용, 텍스트->숫자 변환을 늦추지 않기 - 배경 새로 고침 비활성화: 쿼리 속성 > 백그라운드 새로 고침 해제
7. 피벗 테이블·데이터 모델 관리
여러 피벗 테이블이 같은 원본을 사용한다면 캐시를 공유해야 메모리 사용량이 줄어든다. 데이터 모델(VertiPaq)은 압축 효율이 높아 수백만 행을 안정적으로 처리하나, 열 카드inality가 높은 텍스트는 압축률이 낮아질 수 있다. 불필요 열은 제거하고, 계산 열 대신 측정값을 우선 고려한다.
피벗 캐시 공유 절차 - 기존 피벗 복제 후 데이터 원본 동일 유지 - 다른 피벗이 '다른 캐시'를 만들지 않도록 원본 테이블을 동일 개체로 참조
8. 외부 연결·클라우드 동기화 영향 최소화
외부 연결의 자동 새로 고침, 실시간 공동 편집, 버전 기록, 자동 저장은 대용량에서 체감 지연을 유발한다. 보고서 산출 단계에서는 자동 새로 고침 주기를 늘리고, 필요 시 네트워크 드라이브 대신 로컬 SSD 경로로 복사하여 작업한 뒤 완료본을 동기화한다.
9. VBA로 일시적 최적화 제어
대량 처리 매크로는 화면 갱신, 이벤트, 자동 계산을 일시적으로 꺼야 한다. 처리 후 원복을 보장하기 위해 On Error 핸들링과 Finally 패턴을 사용한다.
Sub FastRun(ByVal work As String) Dim prevCalc As XlCalculation On Error GoTo CleanUp Application.ScreenUpdating = False Application.EnableEvents = False prevCalc = Application.Calculation Application.Calculation = xlCalculationManual Application.DisplayStatusBar = True Application.StatusBar = "작업 중: " & work
'=== 여기에 대량 처리 로직 ===
CleanUp:
Application.StatusBar = False
Application.Calculation = prevCalc
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
셀 쓰기는 배열로 일괄 할당하고, 루프 내 Range 읽기/쓰기를 최소화한다.
Dim arr, i As Long arr = Range("A2:D500000").Value '한 번에 메모리로 For i = LBound(arr,1) To UBound(arr,1) '배열에서 계산 Next i Range("E2:E500000").Value = resultArr '일괄 쓰기
10. 데이터 모델링과 설계 재구성
한 시트에 모든 로직을 쌓는 방식은 유지보수와 성능 모두에 불리하다. 다음의 계층 구조를 권장한다.
| 계층 | 역할 | 도구 | 주요 규칙 |
|---|---|---|---|
| 원천 | 원본 유지 | CSV, DB | 불변, 추가 전용 |
| 정제 | 정규화·조인 | Power Query | 열 최소화, 형식 명확 |
| 집계 | 측정값 계산 | Power Pivot(DAX) | 계산 열 최소화 |
| 표현 | 시각·보고 | 피벗·차트 | 경량 수식, 연결형 차트 |
11. 수식 패턴 교체 예시
11.1 중첩 IF 다단 분기 → XLOOKUP/스위치 테이블
-- 나쁜 예 =IF(A2="A",10,IF(A2="B",15,IF(A2="C",20,0)))
-- 권장
=XLOOKUP(A2, {"A";"B";"C"}, {10;15;20},
0)
11.2 SUMIFS 반복 → 피벗 또는 Power Pivot
-- 나쁜 예: 수백 개 셀에서 동일 SUMIFS =SUMIFS(매출[금액], 매출[제품], H$1, 매출[월], $A2)
-- 권장: 피벗 테이블 값 필드 사용 또는 DAX 측정값
11.3 OFFSET 기반 동적 범위 → 표 구조 참조
-- 나쁜 예 =AVERAGE(OFFSET(B2,0,0,COUNTA(B:B)-1,1))
-- 권장
=AVERAGE(표1[값])
12. 메모리와 64비트 엑셀 고려 사항
수백만 행 수준의 데이터는 32비트 엑셀에서 주소 지정 한계로 불안정해질 수 있다. 64비트 엑셀과 16GB 이상의 메모리를 권장하며, 특히 데이터 모델을 활용할 경우 메모리 여유가 중요하다. 다만 일부 오래된 추가 기능은 64비트 호환성이 부족할 수 있어 호환 목록 점검이 필요하다.
13. 그래픽·UI 렌더링 비용 줄이기
많은 차트, 조건부서식, 스파크라인, 도형은 화면 갱신 비용을 크게 만든다. 대용량 편집 중에는 페이지 레이아웃 보기 대신 일반 보기로 유지하고, 차트를 분리된 시트로 이동하여 본문 시트 렌더링을 가볍게 한다.
14. 데이터 정합성과 오류 처리
수식이 빈 셀을 과도하게 평가하지 않도록 전처리로 공백 제거, 형 변환을 완료한다. 오류 전파를 최소화하기 위해 IFERROR는 외곽에 한 번만 적용하고 내부 로직은 오류를 만들지 않도록 설계한다.
-- 권장 =LET(r, XLOOKUP(...), IF(ISNUMBER(r), r,
0)) '오류 대신 기본값
15. 실전 튜닝 절차: 단계별 액션 플랜
- 백업을 만든 뒤 .xlsb로 저장한다.
- 계산 모드를 수동으로 전환한다.
- 이름 관리자에서 깨진 참조와 전체 열 이름을 정리한다.
- 조건부서식 관리자에서 규칙을 통합하고 범위를 표로 제한한다.
- 데이터 시트를 표로 변환하고 구조 참조로 수식을 교체한다.
- VLOOKUP은 XLOOKUP 또는 INDEX/MATCH로 치환하고 MATCH는 LET으로 캐시한다.
- OFFSET·INDIRECT를 INDEX·구조 참조로 교체한다.
- Power Query로 정제·조인을 이전하고 배경 새로 고침을 끈다.
- 피벗 캐시 공유 여부를 확인하고 불필요 캐시를 제거한다.
- 대량 처리 매크로에 FastRun 패턴을 적용한다.
- 이미지·개체를 일괄 정리한다.
- 완료 후 전체 재계산(F9)·저장, 파일 크기와 열기 속도를 점검한다.
16. 문제 징후별 원인-대응 매트릭스
| 징후 | 가능 원인 | 진단 방법 | 대응 |
|---|---|---|---|
| 입력마다 1초 이상 멈춤 | 휘발성 함수, 전체 열 참조 | 수식 평가 단계 보기 | INDEX 대체, 범위 축소 |
| 저장 시간이 길다 | 이미지·개체 과다, 캐시 중첩 | 파일 크기 추이 비교 | .xlsb 저장, 개체 정리 |
| 열기 시 응답 없음 | 조건부서식 폭증, 이름정의 누수 | 안전 모드 열기 | 규칙 병합, 이름 정리 |
| 피벗 새로 고침 느림 | 원본 조인·필터 남발 | 쿼리 단계 시간 확인 | Power Query로 통합 |
| 스크롤·이동이 버벅임 | 스파크라인·차트 많음 | 개체 수 계산 | 차트 시트 분리 |
17. 자동화된 범위 관리 템플릿
데이터 끝행을 안전하게 추적하기 위한 종단 마커 방식과 전용 이름을 제공한다.
-- 마지막 행 찾기(종단 마커 "Ω" 사용) =XMATCH("Ω", A:A, -1) '아래에서 위로 검색 =INDEX(A:A, XMATCH("Ω", A:A, -1))
-- 안전 합계
=SUM(A2:INDEX(A:A, XMATCH("Ω", A:A, -1)-1))
18. 팀 운영 표준안
- 작업 전 수동 계산 전환과 자동 저장 해제, 완료 후 원복을 공통 규정으로 둔다.
- 데이터 정제는 Power Query, 집계는 피벗/데이터 모델, 표현은 경량 수식으로 역할을 분리한다.
- 대용량 파일은 기본 .xlsb로 관리하고, 배포본은 필요 시 .xlsx로 변환한다.
- 동기화 저장소는 완료본만 업로드하고, 편집은 로컬 SSD에서 수행한다.
- 대량 매크로는 FastRun 패턴을 필수 적용한다.
19. 성능 회귀 방지 팁
- 새 규칙·수식을 추가할 때 범위를 표로 한정한다.
- 조회 키의 데이터 형식 일관성을 유지한다.
- 새 피벗 생성 시 기존 캐시 재사용을 확인한다.
- 정기적으로 이름정의와 조건부서식을 점검한다.
- 대용량 CSV는 가져오기 마법사 또는 Power Query로 불러온다.
FAQ
파일 형식만 바꿔도 속도가 좋아지는가?
.xlsb는 저장·열기 속도와 용량에서 이점이 있는 경우가 많다. 다만 계산 속도는 수식과 구조 최적화가 주도하므로 병행하는 것이 바람직하다.
VLOOKUP을 XLOOKUP으로 바꾸면 항상 빠른가?
항상은 아니다. 핵심은 조회 횟수와 범위, 키 정렬, 중복 MATCH 제거이다. LET로 인덱스를 캐시하면 체감 개선이 크다.
Power Query와 피벗만으로도 충분한가?
대부분의 정제·집계는 충분하다. 복잡한 행 단위 계산이 필요하면 DAX 측정값 또는 제한된 범위의 워크시트 수식을 혼용한다.
조건부서식을 전부 삭제해야 하나?
아니다. 핵심 지표 위주로 규칙을 병합하고 범위를 최소화하면 된다. 요약 시트에만 시각 규칙을 집중한다.
64비트 엑셀로 바꾸면 해결되는가?
대용량 안정성과 메모리 여유는 좋아지지만, 계산 설계가 비효율적이면 느림은 지속된다. 구조 최적화가 먼저이다.
실시간 공동 편집이 느림의 원인인가?
대용량에서는 네트워크 왕복과 자동 저장으로 지연이 커질 수 있다. 중요한 편집은 로컬 복사본에서 수행하고 완료 후 동기화한다.