Ver3.5 엑셀 성능 최적화와 대용량 파일 처리 기법

엑셀 성능 최적화와 대용량 파일 처리 기법
느려터진 엑셀, 이제 로켓처럼 빠르게 만들어보자 🚀
엑셀 파일을 열었는데 커피 한 잔 마시고 와도 아직 로딩 중... 😭 이런 경험 한 번쯤은 있지? 특히 수만 행짜리 데이터를 다루거나, 복잡한 수식이 잔뜩 들어간 파일을 열 때 엑셀이 마치 1990년대 컴퓨터처럼 굴기 시작하면 정말 답답하잖아.
엑셀이 느려지는 데는 명확한 이유가 있어. 그냥 "컴퓨터가 느려서"가 아니라, 파일 구조와 수식 설계, 데이터 관리 방식에서 비롯된 문제야. 원인을 알면 해결책도 보이거든!
NOW(), TODAY(), RAND(), OFFSET(), INDIRECT() 같은 함수들은 셀 하나만 바뀌어도 시트 전체를 재계산해버려. 이게 수천 개 있으면? 지옥이지.
조건부 서식이 수만 행에 걸쳐 적용되어 있으면 렌더링 부하가 엄청나. 특히 복사-붙여넣기를 반복하면 규칙이 중복으로 쌓여서 파일 크기가 폭발적으로 늘어나.
=VLOOKUP(A1, B:B, 1, 0) 처럼 열 전체를 참조하면 엑셀은 100만 개 이상의 셀을 전부 뒤져. 필요한 범위만 딱 지정하는 게 훨씬 효율적이야.
데이터는 A1:A100에만 있는데 서식이 A1:A1048576 전체에 적용되어 있으면 파일 크기가 수십 MB로 뻥튀기돼.
IF 안에 IF 안에 IF... 이런 중첩 구조나 구형 배열 수식(Ctrl+Shift+Enter)은 계산 비용이 매우 높아.
다른 파일을 참조하는 수식이 있으면 파일을 열 때마다 외부 파일을 찾아 연결하려 해서 로딩이 엄청 느려져.
엑셀 최적화의 가장 빠르고 효과적인 방법 중 하나는 계산 모드를 수동으로 전환하는 거야. 특히 대용량 파일 작업 시 이것만으로도 체감 속도가 확 달라져.
수식 탭 → 계산 옵션 → 수동(Manual) 선택
단축키: Ctrl + Alt + F9 (전체 재계산)
또는 VBA로 제어:
' 수동 계산 모드로 전환
Application.Calculation = xlCalculationManual
' 작업 수행 (수식 재계산 없이 빠르게 처리)
' ... 데이터 처리 코드 ...
' 다시 자동 계산으로 복원
Application.Calculation = xlCalculationAutomatic
Application.Calculate ' 한 번만 재계산
VBA 매크로를 실행할 때 이 세 가지를 항상 함께 써줘. 체감 속도가 5~20배 빨라지는 마법이야:
Sub 성능최적화_시작()
Application.ScreenUpdating = False ' 화면 갱신 중지
Application.Calculation = xlCalculationManual ' 자동계산 중지
Application.EnableEvents = False ' 이벤트 처리 중지
Application.DisplayStatusBar = False ' 상태바 업데이트 중지
End Sub
Sub 성능최적화_종료()
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.DisplayStatusBar = True
Application.Calculate
End Sub
| 계산 모드 | 특징 | 권장 상황 |
|---|---|---|
| 자동(Automatic) | 셀 변경 시 즉시 재계산 | 일반 업무, 소규모 파일 |
| 테이블 제외 자동 | 표(Table) 제외하고 자동 계산 | 표가 많은 중간 규모 파일 |
| 수동(Manual) | F9 누를 때만 재계산 | 대용량 파일, VBA 작업 시 |
수식 하나하나의 효율이 모이면 전체 파일 성능이 완전히 달라져. 같은 결과를 내더라도 어떤 함수를 쓰느냐에 따라 계산 속도가 수십 배 차이 날 수 있어!
가장 많이 쓰는 조회 함수들의 성능 차이를 알아보자:
열 삽입 시 오류 위험
대용량에서 느림
열 삽입에 안전
VLOOKUP보다 빠름
가장 직관적
성능도 우수
' 느린 방식 (전체 열 참조)
=VLOOKUP(A1, B:D, 2, 0)
' 빠른 방식 (범위 지정)
=VLOOKUP(A1, $B$1:$D$10000, 2, 0)
' 더 빠른 방식 (INDEX+MATCH)
=INDEX($C$1:$C$10000, MATCH(A1, $B$1:$B$10000, 0))
' 가장 현대적인 방식 (XLOOKUP, Excel 365/2019+)
=XLOOKUP(A1, $B$1:$B$10000, $C$1:$C$10000)
앞서 말한 휘발성 함수들을 비휘발성 대안으로 교체하는 게 중요해:
| 휘발성 함수 (느림) | 대체 방법 (빠름) |
|---|---|
| OFFSET() | INDEX() 사용 — 동일한 동적 참조 가능 |
| INDIRECT() | 직접 참조 또는 구조화된 참조 사용 |
| NOW(), TODAY() | 값으로 붙여넣기 후 필요시만 갱신 |
| RAND(), RANDBETWEEN() | 생성 후 값으로 붙여넣기(Ctrl+Shift+V) |
조건부 합계를 구할 때 어떤 함수가 더 빠를까?
' 단순 조건 합계 → SUMIF가 빠름
=SUMIF($A$1:$A$10000, "서울", $B$1:$B$10000)
' 복합 조건 합계 → SUMIFS 사용
=SUMIFS($B$1:$B$10000, $A$1:$A$10000, "서울", $C$1:$C$10000, ">100")
' 복잡한 계산식 조건 → SUMPRODUCT (단, 느릴 수 있음)
=SUMPRODUCT(($A$1:$A$10000="서울")*($C$1:$C$10000>100)*$B$1:$B$10000)
Excel 365에서 도입된 동적 배열 함수들은 기존 배열 수식(Ctrl+Shift+Enter)보다 훨씬 효율적이야:
' 구형 배열 수식 (느림, Ctrl+Shift+Enter 필요)
{=SUM(IF($A$1:$A$1000="서울", $B$1:$B$1000, 0))}
' 신형 동적 배열 (빠름, Enter만 누르면 됨)
=FILTER($B$1:$B$1000, $A$1:$A$1000="서울")
=SORT(데이터범위, 정렬열번호, 1)
=UNIQUE(범위) ' 중복 제거
=SEQUENCE(행수, 열수, 시작값, 증가값)
엑셀 파일이 100MB를 넘어가면 열기도 전에 지쳐버리지. 파일 크기를 줄이는 건 성능 향상과 직결돼. 실제로 파일 크기를 80% 이상 줄이는 것도 가능해!
파일 크기를 가장 많이 잡아먹는 주범 중 하나가 바로 사용하지 않는 범위의 서식이야.
' 사용 범위 확인 (Ctrl+End로 마지막 셀 확인)
' 실제 데이터가 A1:Z1000에만 있는데
' 서식이 A1:Z1048576 전체에 적용된 경우
' VBA로 사용 범위 외 서식 제거
Sub 서식정리()
Dim ws As Worksheet
Dim lastRow As Long, lastCol As Long
For Each ws In ThisWorkbook.Worksheets
lastRow = ws.UsedRange.Rows.Count
lastCol = ws.UsedRange.Columns.Count
' 마지막 행 이후 서식 제거
If lastRow < ws.Rows.Count Then
ws.Rows(lastRow + 1 & ":" & ws.Rows.Count).ClearFormats
End If
' 마지막 열 이후 서식 제거
If lastCol < ws.Columns.Count Then
ws.Columns(lastCol + 1).Resize(, ws.Columns.Count - lastCol).ClearFormats
End If
Next ws
MsgBox "서식 정리 완료!"
End Sub
| 파일 형식 | 특징 | 권장 용도 |
|---|---|---|
| .xlsx | 표준 형식, XML 기반 압축 | 일반 업무 파일 |
| .xlsb | 바이너리 형식, 가장 작고 빠름 | 대용량 데이터 파일 ⭐ |
| .xlsm | 매크로 포함 형식 | VBA 매크로 포함 파일 |
| .xls | 구형 형식, 비효율적 | 사용 지양 ❌ |
엑셀에 삽입된 이미지가 파일 크기를 엄청나게 키울 수 있어. 이미지 압축은 필수야!
수십만, 수백만 행의 데이터를 엑셀에서 다뤄야 할 때 어떻게 해야 할까? 그냥 붙여넣기 했다가는 엑셀이 뻗어버리거나 몇 시간이 걸릴 수도 있어. 스마트하게 처리하는 방법을 알아보자!
파워 쿼리는 엑셀에서 대용량 데이터를 처리하는 가장 강력한 도구야. 데이터 탭 → 데이터 가져오기 및 변환에서 접근할 수 있어.
셀을 하나씩 읽고 쓰는 것은 엑셀에서 가장 느린 작업이야. 대신 배열에 한 번에 읽어서 처리하는 방식을 써야 해:
' ❌ 느린 방식: 셀을 하나씩 읽고 쓰기
Sub 느린방식()
Dim i As Long
For i = 1 To 100000
If Cells(i, 1).Value > 100 Then
Cells(i, 2).Value = Cells(i, 1).Value * 2
End If
Next i
End Sub
' ✅ 빠른 방식: 배열에 한 번에 읽고 처리 후 한 번에 쓰기
Sub 빠른방식()
Dim arrInput As Variant
Dim arrOutput() As Variant
Dim i As Long
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
' 한 번에 배열로 읽기 (셀 접근 1회)
arrInput = Range("A1:A" & lastRow).Value
ReDim arrOutput(1 To lastRow, 1 To 1)
' 메모리에서 처리 (셀 접근 없음)
For i = 1 To lastRow
If arrInput(i, 1) > 100 Then
arrOutput(i, 1) = arrInput(i, 1) * 2
End If
Next i
' 한 번에 쓰기 (셀 접근 1회)
Range("B1:B" & lastRow).Value = arrOutput
End Sub
피벗 테이블은 대용량 데이터 분석의 핵심 도구지만, 잘못 사용하면 오히려 성능을 잡아먹어:
엑셀은 생각보다 메모리를 많이 먹어. 특히 32비트 엑셀은 최대 2GB까지만 사용할 수 있어서 대용량 작업 시 메모리 부족 오류가 자주 발생해. 64비트 엑셀을 사용하면 이 제한이 없어지지만, 그래도 메모리 관리는 중요해!
' 1. 객체 변수 해제 (메모리 누수 방지)
Sub 메모리관리_예시()
Dim wb As Workbook
Dim ws As Worksheet
Dim rng As Range
Set wb = Workbooks.Open("C:\data\bigfile.xlsx")
Set ws = wb.Worksheets(1)
Set rng = ws.Range("A1:Z100000")
' 작업 수행
' ...
' 반드시 객체 해제!
Set rng = Nothing
Set ws = Nothing
wb.Close SaveChanges:=False
Set wb = Nothing
End Sub
' 2. 대용량 배열 처리 후 메모리 해제
Sub 배열메모리해제()
Dim bigArray() As Variant
' 대용량 배열 사용
ReDim bigArray(1 To 1000000, 1 To 10)
' 작업 수행...
' 배열 메모리 해제
Erase bigArray
End Sub
| 구분 | 32비트 엑셀 | 64비트 엑셀 |
|---|---|---|
| 최대 메모리 | 약 2GB | 시스템 RAM 전체 활용 |
| 대용량 처리 | 메모리 부족 오류 위험 | 안정적 처리 가능 |
| VBA 호환성 | 구형 DLL 호환 좋음 | 일부 구형 코드 수정 필요 |
| 권장 상황 | 구형 매크로 사용 시 | 대용량 데이터 작업 시 ⭐ |
엑셀 2007부터 멀티스레드 계산(Multi-threaded Calculation)을 지원해. 기본적으로 활성화되어 있지만 확인하고 최적화할 수 있어:
이론은 충분히 배웠으니 이제 실전에서 바로 쓸 수 있는 전략들을 정리해볼게. 재능넷 같은 플랫폼에서 데이터 분석 서비스를 제공하는 분들이라면 이 부분이 특히 유용할 거야!
수백만 행의 CSV 파일을 엑셀에서 처리해야 할 때 사용하는 전략이야:
' 대용량 CSV를 청크(Chunk) 단위로 처리하는 VBA
Sub CSV_청크처리()
Dim fileNum As Integer
Dim lineData As String
Dim chunkSize As Long
Dim lineCount As Long
Dim dataArray() As String
Dim chunkArray() As Variant
Dim i As Long
chunkSize = 10000 ' 한 번에 처리할 행 수
fileNum = FreeFile
Open "C:\data\bigdata.csv" For Input As #fileNum
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
lineCount = 0
ReDim chunkArray(1 To chunkSize, 1 To 10)
Do While Not EOF(fileNum)
Line Input #fileNum, lineData
lineCount = lineCount + 1
dataArray = Split(lineData, ",")
Dim j As Integer
For j = 0 To UBound(dataArray)
If j < 10 Then
chunkArray(lineCount Mod chunkSize + 1, j + 1) = dataArray(j)
End If
Next j
' 청크가 가득 차면 시트에 쓰기
If lineCount Mod chunkSize = 0 Then
Dim startRow As Long
startRow = lineCount - chunkSize + 1
Sheets(1).Range("A" & startRow).Resize(chunkSize, 10).Value = chunkArray
ReDim chunkArray(1 To chunkSize, 1 To 10)
DoEvents ' UI 응답성 유지
End If
Loop
Close #fileNum
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "처리 완료! 총 " & lineCount & "행 처리됨"
End Sub
엑셀의 최대 행 수는 1,048,576행이야. 이를 초과하는 데이터는 반드시 분할 처리해야 해:
계산이 완료된 수식은 값으로 변환해서 저장하면 파일 크기와 계산 부하를 크게 줄일 수 있어:
' 선택 범위의 수식을 값으로 변환
Sub 수식을값으로변환()
Dim rng As Range
' 현재 선택 범위 또는 특정 범위 지정
Set rng = Selection ' 또는 Range("A1:Z10000")
' 복사 후 값으로 붙여넣기
rng.Copy
rng.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
MsgBox "수식이 값으로 변환되었습니다!"
End Sub
' 시트 전체의 수식을 값으로 변환
Sub 시트전체_값변환()
With ActiveSheet.UsedRange
.Value = .Value
End With
End Sub
기본 최적화를 마스터했다면 이제 한 단계 더 나아가보자. 이 기법들은 엑셀 파워 유저들이 실제로 사용하는 고급 테크닉이야!
일반 범위 대신 엑셀 테이블(Ctrl+T)을 사용하면 여러 성능상 이점이 있어:
이름 정의를 잘 활용하면 수식 가독성과 성능을 동시에 높일 수 있어:
' 동적 이름 정의 (데이터 범위가 변해도 자동 추적)
' 수식 탭 → 이름 관리자 → 새로 만들기
' 동적 범위 수식 예시 (OFFSET 대신 INDEX 사용 - 비휘발성!)
' 이름: 동적데이터범위
' 참조 대상: =Sheet1!$A$1:INDEX(Sheet1!$A:$A, COUNTA(Sheet1!$A:$A))
' VBA에서 이름 정의 생성
Sub 이름정의_생성()
' 동적 범위 이름 정의
ThisWorkbook.Names.Add _
Name:="동적데이터", _
RefersToR1C1:="=Sheet1!R1C1:INDEX(Sheet1!C1,COUNTA(Sheet1!C1))"
End Sub
수십만 건의 데이터에서 반복적인 조회가 필요할 때 VBA의 Dictionary 객체를 사용하면 VLOOKUP보다 훨씬 빠른 조회가 가능해:
' Dictionary를 활용한 초고속 조회
Sub Dictionary_조회예시()
Dim dict As Object
Dim ws As Worksheet
Dim i As Long
Dim lastRow As Long
Dim lookupData As Variant
Dim resultData As Variant
Set dict = CreateObject("Scripting.Dictionary")
Set ws = ThisWorkbook.Sheets(1)
' 참조 테이블을 Dictionary에 로드 (1회만 실행)
lastRow = ws.Cells(ws.Rows.Count, "D").End(xlUp).Row
Dim refData As Variant
refData = ws.Range("D1:E" & lastRow).Value
For i = 1 To UBound(refData, 1)
If Not dict.Exists(refData(i, 1)) Then
dict.Add refData(i, 1), refData(i, 2)
End If
Next i
' 조회 데이터 배열로 읽기
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
lookupData = ws.Range("A1:A" & lastRow).Value
ReDim resultData(1 To lastRow, 1 To 1)
' Dictionary로 초고속 조회 (해시 테이블 기반)
For i = 1 To lastRow
If dict.Exists(lookupData(i, 1)) Then
resultData(i, 1) = dict(lookupData(i, 1))
Else
resultData(i, 1) = "없음"
End If
Next i
' 결과 한 번에 쓰기
ws.Range("B1:B" & lastRow).Value = resultData
Set dict = Nothing
MsgBox "완료! Dictionary 조회는 VLOOKUP보다 10~50배 빠릅니다!"
End Sub
일반 엑셀의 한계를 넘어서는 대용량 데이터 분석이 필요하다면 파워 피벗이 답이야:
최적화를 하려면 먼저 어디가 병목인지 알아야 해. 엑셀에는 성능을 진단할 수 있는 도구들이 있어!
' 수식/코드 실행 시간 측정
Sub 실행시간측정()
Dim startTime As Double
Dim endTime As Double
startTime = Timer ' 시작 시간 기록
' 측정할 코드 실행
' ... 여기에 코드 ...
endTime = Timer ' 종료 시간 기록
MsgBox "실행 시간: " & Format(endTime - startTime, "0.000") & "초"
End Sub
' 더 정밀한 측정 (밀리초 단위)
Sub 정밀시간측정()
Dim startTime As Long
startTime = GetTickCount() ' Windows API 활용
' 측정할 코드
MsgBox "실행 시간: " & (GetTickCount() - startTime) & "ms"
End Sub
' Windows API 선언 (모듈 상단에 추가)
#If VBA7 Then
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
지금까지 엑셀 성능 최적화와 대용량 파일 처리에 대한 핵심 기법들을 살펴봤어. 처음에는 복잡해 보일 수 있지만, 하나씩 적용해나가다 보면 엑셀이 완전히 다른 도구처럼 느껴질 거야! 🚀
엑셀 최적화는 한 번에 모든 걸 바꾸려 하기보다 가장 효과가 큰 것부터 하나씩 적용하는 게 좋아. 특히 VBA 배열 처리와 ScreenUpdating 제어는 투자 대비 효과가 가장 크니까 이것부터 시작해봐!
엑셀 관련 스킬을 더 발전시키고 싶다면 재능넷에서 엑셀 전문가들의 강의나 서비스를 찾아보는 것도 좋은 방법이야. 다양한 실무 경험을 가진 전문가들이 맞춤형 도움을 줄 수 있거든!
관련 키워드
댓글 0
지식인의 숲 - 지적 재산권 보호 고지
지적 재산권 보호 고지
- 저작권 및 소유권: 본 컨텐츠는 재능넷의 독점 AI 기술로 생성되었으며, 대한민국 저작권법 및 국제 저작권 협약에 의해 보호됩니다.
- AI 생성 컨텐츠의 법적 지위: 본 AI 생성 컨텐츠는 재능넷의 지적 창작물로 인정되며, 관련 법규에 따라 저작권 보호를 받습니다.
- 사용 제한: 재능넷의 명시적 서면 동의 없이 본 컨텐츠를 복제, 수정, 배포, 또는 상업적으로 활용하는 행위는 엄격히 금지됩니다.
- 데이터 수집 금지: 본 컨텐츠에 대한 무단 스크래핑, 크롤링, 및 자동화된 데이터 수집은 법적 제재의 대상이 됩니다.
- AI 학습 제한: 재능넷의 AI 생성 컨텐츠를 타 AI 모델 학습에 무단 사용하는 행위는 금지되며, 이는 지적 재산권 침해로 간주됩니다.

댓글 작성
이 글에 대한 여러분의 생각을 들려주세요
로그인이 필요합니다
댓글을 작성하려면 먼저 로그인해주세요.