스프레드시트를 활용해 조금씩 복잡한 문서를 만들기 시작하면, 고정된 범위가 아니라 상황에 따라 유연하게 움직이는 '동적 범위'가 필요해집니다. 이때 많은 독학러들이 인터넷 검색을 통해 INDIRECT 함수나 OFFSET 함수를 접하고 이를 적극적으로 활용하기 시작합니다. 특정 셀의 텍스트를 그대로 가져와 수식의 범위로 변환해 주거나, 기준점에서 몇 칸 떨어진 곳을 자동으로 지정해 주니 처음에는 마치 마법 같은 편리함을 느낍니다.
하지만 이 함수들을 시트 이곳저곳에 남발하는 순간, 어느 날부터 파일이 열리는 데 한참이 걸리고 숫자 하나만 바꿔도 화면이 멈추는 '랙(Lag)' 현상을 겪게 됩니다. 내가 해보니 처음에는 데이터가 적어 문제가 없다가, 로우(Row)가 수천 줄로 늘어나는 순간 시트 전체가 마비되는 경험을 하게 됩니다. 왜 이런 현상이 발생하며, 어떻게 수식을 다이어트해야 시트의 속도를 다시 살릴 수 있는지 그 원리와 대안을 알아보겠습니다.
1. 보이지 않는 재계산의 늪: 휘발성 함수의 무서움
INDIRECT와 OFFSET 함수가 스프레드시트를 느리게 만드는 본질적인 이유는 이들이 '휘발성 함수(Volatile Function)'이기 때문입니다. 일반적인 SUM이나 VLOOKUP 같은 함수는 수식에 참조된 셀의 값이 바뀔 때만 스스로를 재계산합니다. 관련 없는 다른 셀을 수정할 때는 가만히 대기하고 있으므로 컴퓨터 자원을 효율적으로 사용합니다.
반면 휘발성 함수는 시트 내부의 '어떤 셀이든' 변경되는 순간, 자신과 아무런 연관이 없는 변경 사항일지라도 무조건 수식을 처음부터 다시 계산합니다. 예를 들어 A열에 OFFSET 함수를 수백 개 써두었다면, 전혀 상관없는 Z열의 오타 하나를 고쳐도 A열의 수백 개 수식이 동시에 재계산 작업을 수행합니다. 이 과정이 반복되면서 브라우저의 메모리가 고갈되고, 구글 서버와의 통신 속도가 저하되며 시트 전체가 무거워지는 것입니다. 편리함 뒤에 숨겨진 엄청난 성능 저하의 대가인 셈입니다.
2. INDIRECT를 대체하는 비휘발성 동적 참조: INDEX 함수의 재발견
가장 흔하게 발생하는 실수는 다른 시트의 이름을 셀에 적어두고 =INDIRECT(A1&"!B2") 형태로 동적 참조를 하는 경우입니다. 시트가 많아질 때 유용해 보이지만, 이를 비휘발성 함수인 INDEX로 대체하면 속도를 획기적으로 개선할 수 있습니다.
INDEX 함수는 단순히 특정 행과 열의 값을 가져오는 역할만 하는 것이 아니라, 수식의 조합에 따라 '셀의 주소(참조)'를 반환하는 숨겨진 능력이 있습니다. 예를 들어 범위를 유연하게 늘려가며 합계를 구하고 싶을 때, 많은 이들이 =SUM(A1:OFFSET(A1, B1, 0)) 같은 구조를 사용합니다. 이는 전형적인 속도 저하의 원인이 됩니다.
이를 비휘발성인 INDEX로 바꾸면 =SUM(A1:INDEX(A:A, B1)) 형태로 작성할 수 있습니다. 이 수식은 B1 셀에 적힌 숫자만큼의 행까지만 정확히 범위를 지정해 주면서도, 휘발성 성질이 없기 때문에 다른 셀을 만질 때 불필요한 재계산을 하지 않습니다. 구조가 조금 낯설 수 있지만, 대용량 데이터를 다룰 때는 이 작은 차이가 시트의 생명을 좌우합니다.
3. 동적 범위의 완전한 해답: 수식 대신 필터와 Named Range 활용하기
매번 변하는 데이터의 끝을 잡기 위해 OFFSET을 썼다면, 이제는 구글 스프레드시트의 고유 기능이나 수식 구조를 바꾸는 것이 좋습니다. 가장 좋은 방법 중 하나는 행의 제한을 두지 않는 '오픈 범위(Open-ended Range)'를 사용하는 것입니다. 단순히 =SUM(A2:A100) 대신 =SUM(A2:A)로 작성하면, 데이터가 아래로 아무리 추가되어도 수식을 수정하거나 OFFSET을 쓸 필요 없이 자동으로 전체 합계에 반영됩니다.
만약 중간에 빈칸이 있거나 특정 조건에 맞는 데이터만 동적으로 추려내야 해서 어쩔 수 없이 수식을 썼다면, FILTER 함수나 QUERY 함수를 검토해 보세요. 이 함수들은 휘발성이 아니면서도 조건에 맞는 데이터 범위를 동적으로 배열(Array) 형태로 뿌려주기 때문에, 훨씬 안전하고 빠르게 동적 화면을 구현할 수 있습니다.
도구를 잘 쓰는 것보다 더 중요한 것은 시트가 감당할 수 있는 연산의 한계를 이해하는 것입니다. 지금 사용하는 시트가 유독 느리다면, [Ctrl + F]를 눌러 시트 내에 INDIRECT나 OFFSET이 얼마나 숨어있는지 먼저 점검해 보시기 바랍니다.
핵심 요약
INDIRECT와 OFFSET은 시트 내의 작은 변화에도 전체가 재계산되는 '휘발성 함수'이므로 수천 행 이상의 대용량 데이터에 남발하면 심각한 속도 저하를 유발합니다.
동적 범위를 지정할 때는 휘발성 함수 대신 INDEX 함수의 참조 반환 성질을 활용하거나,
A2:A형태의 오픈 범위를 사용하는 것이 성능 최적화에 유리합니다.불필요한 참조 수식을 줄이고, 조건별 동적 데이터 추출이 필요할 때는 비휘발성이면서 강력한 FILTER나 QUERY 함수로 구조를 전환해야 합니다.
다음 편 예고
스프레드시트의 내부 성능을 아끼는 법을 배웠으니, 다음 제12편에서는 외부 데이터를 실시간으로 긁어오는 "웹 크롤링의 함정 - IMPORTXML과 IMPORTHTML로 가져온 데이터가 수시로 깨지고 에러(N/A)가 나는 이유와 주기적 동기화 관리법"에 대해 상세히 다루어 보겠습니다.
댓글 유도 질문
수식을 몇 개 넣지 않았는데도 시트를 켤 때마다 '계산 중...'이라는 메시지가 뜨며 멈췄던 적이 있으신가요? 현재 시트 속도를 떨어뜨리고 있는 주범이 무엇인지 수식을 댓글로 공유해 주시면 대안 수식을 찾아드릴게요!
0 댓글