약 10분 읽기
안녕하세요, 황민입니다. 오늘은 RPA 엔지니어로서 실제 현장에서 겪었던 엑셀 대용량 데이터 처리 관련 경험을 공유하려고 합니다. 특히 UiPath에서 ‘Read Range’와 ‘Filter DataTable’ 액티비티를 사용했을 때의 속도 차이, 그리고 대용량 데이터를 어떻게 효율적으로 다루는지에 대한 제 경험을 솔직하게 풀어보겠습니다.
5만 행 엑셀, 어느 액티비티를 써야 할까요?
RPA 프로젝트를 진행하다 보면 엑셀 파일을 다루는 작업은 정말 흔하게 접하게 됩니다. 제조, 금융, 건설업 등 다양한 산업군의 고객사 프로세스를 자동화하면서 엑셀은 거의 필수적으로 등장했죠. 그런데 엑셀 파일의 크기가 커지면 이야기가 달라집니다. 수백, 수천 건은 문제가 없지만, 5만 행, 10만 행을 넘어가기 시작하면 평소와는 다른 접근이 필요하다는 것을 몸소 느끼게 됩니다.
제가 처음 RPA를 배우고 현장에 투입되었을 때, 습관적으로 엑셀 데이터를 읽어와서 처리할 때는 ‘Read Range’ 액티비티를 가장 먼저 떠올렸습니다. 데이터를 테이블 형태로 읽어오는 가장 직관적인 방법이니까요. 그런데 어느 날, 5만 행이 넘는 대용량 엑셀 파일을 처리해야 하는 과제가 주어졌습니다. 데이터를 읽어오는 데만 해도 시간이 꽤 걸렸고, 이후 특정 조건에 맞는 데이터를 필터링하는 과정에서 예상치 못한 병목 현상이 발생했습니다.
당시 상황을 좀 더 구체적으로 말씀드리자면, ‘Read Range’로 엑셀 전체를 DataTable로 읽어온 뒤, ‘Filter DataTable’ 액티비티를 사용해서 원하는 데이터를 걸러내는 방식이었습니다. 처음에는 이 방식이 가장 효율적이라고 생각했죠. 하지만 5만 행 이상의 데이터를 처리할 때, ‘Filter DataTable’ 액티비티가 생각보다 많은 리소스를 소모하고 시간이 오래 걸린다는 것을 알게 되었습니다. 마치 큰 웅덩이에 고기를 잡으려다 잘 안 잡히는 느낌이랄까요?

‘Filter DataTable’의 한계와 LINQ의 등장
‘Filter DataTable’ 액티비티는 사용하기 편리하고 직관적이라는 장점이 있습니다. 하지만 내부적으로는 엑셀 데이터를 한 줄씩 읽어와서 조건을 비교하는 방식으로 동작하는 경우가 많습니다. 데이터 양이 많아질수록 이 과정에서 발생하는 시간 지연은 기하급수적으로 늘어날 수밖에 없습니다. 특히 복잡한 조건이나 여러 개의 필터를 적용할 때는 성능 저하가 더욱 두드러졌습니다.
이런 상황에서 저는 다른 방법을 모색하기 시작했습니다. ‘Filter DataTable’로는 한계가 있다고 느꼈고, 좀 더 빠르고 효율적인 방법을 찾고 싶었죠. 그러던 중, UiPath 커뮤니티나 기술 문서에서 ‘LINQ’라는 것을 접하게 되었습니다. LINQ(Language Integrated Query)는 .NET 프레임워크에서 제공하는 강력한 데이터 쿼리 기능인데, DataTable과 같은 컬렉션을 대상으로 매우 빠르고 유연하게 데이터를 조회하고 조작할 수 있다는 장점이 있었습니다.
처음에는 LINQ가 다소 어렵게 느껴졌습니다. SQL과 비슷한 문법을 사용하지만, 프로그래밍 언어 안에 녹아들어 있다는 점이 신선했죠. 하지만 몇 가지 예제를 따라 해보고, 실제로 ‘Filter DataTable’ 대신 LINQ를 사용해서 데이터를 필터링하는 코드를 작성해보니, 그 성능 차이에 깜짝 놀랐습니다. 5만 행이 넘는 데이터에서 특정 조건을 만족하는 행들을 찾아내는 속도가 ‘Filter DataTable’을 사용할 때보다 훨씬 빨랐습니다. 특히 복잡한 조건일수록 그 차이는 더욱 극명하게 드러났습니다.
‘Read Range’ vs LINQ: 실제 속도 비교 (제 경험 기반)
제가 직접 경험했던 사례를 바탕으로 속도 차이를 좀 더 명확하게 설명해 드릴게요. 어느 제조업 고객사의 월말 보고서 자동화 프로젝트였습니다. 수십만 건의 생산 데이터를 엑셀 파일로 받아와서 특정 설비의 불량률을 계산하고, 이를 기준으로 상위 10개 불량 설비를 추출하는 업무였죠. 엑셀 파일의 크기는 약 10만 행이었습니다.
시나리오 1: ‘Read Range’ + ‘Filter DataTable’
- ‘Read Range’로 엑셀 전체를 DataTable로 읽어옴 (약 10~15분 소요)
- ‘Filter DataTable’ 액티비티를 사용하여 특정 조건(설비 ID, 날짜 등)에 맞는 데이터 필터링 (약 5~10분 소요)
- 필터링된 결과에서 상위 10개 불량 설비 추출 (별도 로직 필요)
- 총 소요 시간: 약 15~25분
이 방식은 처음에는 직관적이고 쉬웠지만, 10만 행 데이터에서는 분명히 부담스러운 시간이었습니다. 봇 운영 횟수가 많아질수록 전체 업무 처리 시간과 비용에 상당한 영향을 미쳤죠.
시나리오 2: ‘Read Range’ + LINQ (Assign 액티비티 활용)
- ‘Read Range’로 엑셀 전체를 DataTable로 읽어옴 (약 10~15분 소요 – 시나리오 1과 동일)
- Assign 액티비티와 LINQ를 사용하여 데이터 필터링 및 상위 10개 설비 추출 (약 1~2분 소요)
- 총 소요 시간: 약 11~17분
시나리오 2에서 LINQ를 사용했을 때, ‘Filter DataTable’을 사용하는 것보다 훨씬 빠른 속도를 경험할 수 있었습니다. 특히 Assign 액티비티 안에서 LINQ 쿼리를 작성하여 필요한 데이터를 바로 추출하는 방식이었습니다. 예를 들어, 다음과 같은 형태의 LINQ 쿼리를 사용했죠 (실제 코드는 더 복잡하지만 개념만):
(From row In dataTable.AsEnumerable()
Where row.Field(Of String)("설비ID").Contains("A") AndAlso row.Field(Of DateTime)("날짜").Year = 2023
Select row.Field(Of String)("불량률")).Take(10)
이처럼 LINQ는 람다 표현식이나 쿼리 문법을 통해 데이터에 접근하고 조건을 적용하기 때문에, 내부적으로 잘 맞는 방식으로 데이터를 처리합니다. ‘Filter DataTable’이 엑셀의 ‘필터’ 기능을 흉내 내는 느낌이라면, LINQ는 데이터베이스 쿼리처럼 데이터를 직접 다루는 느낌이랄까요? 속도 차이가 날 수밖에 없는 구조였습니다.
물론 ‘Read Range’ 액티비티 자체도 엑셀 파일을 읽어오는 과정이므로, 데이터 양이 많을수록 시간은 걸립니다. 하지만 이 부분은 ‘Filter DataTable’로 추가적인 필터링을 하는 시간과 비교했을 때, LINQ를 사용함으로써 전체 시간을 크게 단축할 수 있었습니다.
대용량 엑셀 처리, 또 다른 팁: 청크 처리
LINQ가 성능 향상에 큰 도움을 주었지만, 10만 행 이상의 데이터를 한 번에 메모리에 올리는 것 자체가 부담스러울 때도 있습니다. 특히 서버 리소스가 제한적이거나, 다른 프로세스와 동시에 실행될 때 문제가 발생할 수 있죠. 이럴 때 제가 사용하는 또 다른 방법은 ‘청크(Chunk) 처리’입니다.
청크 처리는 대용량 데이터를 한 번에 다루지 않고, 일정한 크기의 작은 덩어리(청크)로 나누어 순차적으로 처리하는 방식입니다. 예를 들어, 10만 행의 엑셀 파일이라면 1만 행씩 10개의 청크로 나누어 각 청크를 개별적으로 읽고 처리하는 것입니다. 각 청크를 처리할 때마다 메모리에서 해당 데이터를 해제해주면, 시스템 전체의 메모리 부담을 크게 줄일 수 있습니다.
UiPath에서 청크 처리를 구현하는 방법은 여러 가지가 있습니다. 가장 간단한 방법은 ‘Read Range’ 액티비티의 ‘Range’ 속성을 동적으로 변경하면서 여러 번 호출하는 것입니다. 예를 들어, 10만 행 데이터를 1만 행씩 처리한다고 가정하면, 다음과 같은 방식으로 Range를 지정할 수 있습니다.
- 첫 번째 청크: “A1:C10000”
- 두 번째 청크: “A10001:C20000”
- …
- 열 번째 청크: “A90001:C100000”
이때 반복문(For Each Loop)을 활용하여 시작 행과 끝 행을 계산하고, ‘Read Range’ 액티비티의 Range 속성에 동적으로 입력해주면 됩니다. 각 청크를 읽어온 후에는 바로 필요한 로직(LINQ 필터링 포함)을 적용하고, 처리된 데이터는 별도의 결과 테이블에 누적하거나 파일로 저장합니다. 모든 청크 처리가 완료되면 최종 결과를 얻게 되는 것이죠.
이 청크 처리 방식은 메모리 사용량을 최적화하는 데 매우 효과적이며, 대용량 파일을 안정적으로 처리할 수 있게 해줍니다. 물론 데이터 처리 로직이 조금 더 복잡해질 수 있지만, 안정성과 성능 면에서 큰 이점을 얻을 수 있습니다.

결론: 상황에 맞는 최적의 선택
오늘 제가 공유해드린 ‘Read Range’ vs ‘Filter DataTable’ 속도 비교, 그리고 LINQ와 청크 처리 방식은 모두 실제 현장에서 제가 겪었던 문제들을 해결하기 위해 시도했던 방법들입니다. 정리하면, 엑셀 대용량 데이터를 처리할 때는:
- 데이터 양이 적거나 중간 정도라면: ‘Read Range’ + ‘Filter DataTable’ 조합도 충분히 빠르고 직관적입니다.
- 데이터 양이 많고(5만 행 이상), 빠른 처리가 필요하다면: ‘Read Range’로 데이터를 읽어온 후, ‘Assign’ 액티비티와 LINQ를 활용하는 것이 훨씬 효율적입니다.
- 메모리 사용량 최적화가 중요하거나, 매우 큰 데이터를 다룬다면: 청크 처리 방식을 도입하여 안정성을 확보하는 것이 좋습니다.
RPA 엔지니어로서 저는 항상 ‘가장 효율적이고 안정적인 방법’을 고민합니다. 때로는 익숙한 액티비티 대신 새로운 기술을 도입해야 할 때도 있고, 여러 기법을 조합해야 할 때도 있습니다. 오늘 말씀드린 내용이 여러분의 엑셀 대용량 데이터 처리 고민에 조금이나마 도움이 되었기를 바랍니다. 혹시 저와 비슷한 경험을 하셨거나, 다른 팁이 있다면 댓글로 공유해주시면 감사하겠습니다!
다음에는 제가 직접 구축한 n8n+Gemini 자동 발행 시스템 구축 경험에 대해 이야기해보겠습니다. 기대해주세요!
함께 볼 글
이 글과 이어지는 내용은 아래에 정리해뒀다.