커뮤니티 채널
전략가의무기들(멤버십)
DA전략코칭프로그램수강생전용
community_post_owner
하길우
크리에이터
[Q&A] 좋은질문과 답
[분석 환경/신입/취준생] 클라우드(GCP) 환경에서 데이터 조회할 때 반드시 알아야하는 조회 원칙

대부분의 회사에서, "파티셔닝"이라는 것을 통해 데이터 조회 비용을 아낍니다.

저희 회사에서도 이런 원칙이 있는데요.

파티셔닝 및 클러스터링 적용: 대용량 테이블 조회 시 partition_day나 ts_kst와 같은 파티셔닝/클러스터링 컬럼을 WHERE 절에 포함하여 스캔 범위를 줄이고 비용을 절감합니다.


이 개념은 부트캠프 분석 환경에서 다루지 않고 현업에서만 다루게 되는 경우가 흔합니다.

이유는 부트캠프에서 쓰는 데이터의 양이 많지 않아서 그래요. 데이터가 적으니 스캔 범위를 줄여서 비용 절감을 할 필요가 없거든요.

참고로 데이터 조회 비용은 딱 2가지라고 생각하시면 편합니다.

  1. 조회하는 데이터의 크기 -> 스캔 비용
  2. 데이터를 가지고 연산하는데 들어가는 비용 -> 연산 비용

일반적으로 연산 비용이 이슈가 되려면 데이터가 많이 커야합니다. (엄밀히는 복잡한 조인연산을 긴 시간동안 하면 비용이 많이나가죠.) 하지만, 일정 시간 이상 돌면 조회 세션이 죽는 경우도 많고, 데이터가 많이 큰 경우는 클라우드보다 보통 온프레미스로 전환을 하게 되죠.

그래서 가장 먼저 생각해야할 것은 스캔 비용입니다.

모든 초심자분들이 처음에는 대용량 쿼리를 날리는 실수를 하면서 성장하지만, 신기하게도 쿼리 비용을 줄이는 '방법'을 알지만, '파티셔닝'이라는 개념에 대해 공부하는 경우는 적었습니다. 시간이 지나면 익숙해지다보니, 안다고 착각하는 경우가 많아지는데요. 저는 늘 익숙해지기 전에 제대로 공부해놓자 주의입니다.

수많은 데이터 엔지니어링 개념 중에, 데이터 취급자(분석가 포함한 모든 데이터 조회자)가 알았을 때 가장 가성비가 좋은 건 역시, 파티셔닝이라고 생각해 오늘은 현업에서 데이터를 조회한 경험이 없는 모든 분들을 위해서 "파티셔닝"이라는 개념을 알려드리려합니다.


파티셔닝(Partitioning)이란 쉽게 말해 '데이터를 날짜별(또는 특정 기준별)로 쪼개서 각기 다른 서랍에 보관하는 것'입니다.

우리가 10년 치 일기가 적힌 두꺼운 노트를 가지고 있다고 상상해 볼까요?

만약 "2023년 12월 25일에 무슨 일이 있었지?"를 찾으려면, 파티셔닝이 안 된 데이터베이스는 첫 장부터 끝 장까지 모든 페이지를 다 넘겨봐야 합니다. 이를 풀 스캔(Full Scan)이라고 부르며, 시간도 오래 걸리고 무엇보다 빅쿼리 환경에서는 엄청난 비용을 발생시킵니다. 빅쿼리는 기본적으로 '우리가 쿼리를 돌릴 때 읽어 들인 데이터의 양(스캔량)'만큼 돈을 과금하기 때문입니다.

하지만 파티셔닝이 되어 있다면 어떨까요? 일기장이 '연도별/월별/일별'로 깔끔하게 서랍으로 나뉘어 있는 것과 같습니다. 2023년 12월 25일 서랍만 쏙 열어서 그 안의 데이터만 읽으면 되죠. 스캔하는 데이터의 양이 획기적으로 줄어듭니다.


여기서 GCP에는 또 하나의 데이터 절감을 위한 개념이 있는데요. 바로 "클러스터링"입니다.

클러스터링(Clustering)은 그 서랍 안에서 한 번 더 '정렬'을 해두는 개념입니다.

예를 들어 날짜별(파티셔닝)로 모인 서랍 안에서, 다시 '유저 ID' 순서대로(클러스터링) 서류를 정렬해 두는 식입니다. 그러면 특정 날짜에 특정 유저가 한 행동을 찾을 때 훨씬 더 빠르고 저렴하게 데이터를 조회할 수 있습니다.



‼️ 실전! 쿼리 작성 시 주의사항

현업에서 빅쿼리나 HEX를 사용해 데이터를 추출할 때는, 쿼리를 실행하기 전에 반드시 WHERE 절에 파티셔닝 컬럼(예: partition_day, ts_kst, date 등)이 포함되어 있는지 확인하는 습관을 들여야 합니다.

❌ 나쁜 예 (과금 폭탄의 주범)

SELECT user_id, event_name

FROM `company.dataset.user_events`

LIMIT 100

빅데이터 환경에서 일반적으로 LIMIT는 조회비용을 줄이지 못합니다. 위 쿼리는 사실상 풀스캔 쿼리가됩니다.


✅ 좋은 예 (비용 절감과 속도 향상)

SELECT user_id, event_name

FROM `company.dataset.user_events`

WHERE partition_day BETWEEN '2024-03-01' AND '2024-03-31' -- 조회 기간을 명시해 스캔 범위를 제한!

AND event_name = 'purchase' -- 만약 event_name에 클러스터링이 걸려있다면, 더 범위를 축약해줍니다.


GCP에는 DryRun이라는 개념이 있습니다. 쿼리를 실행(Run)하기 전에, 에디터 화면에 나타나는 '예상 데이터 처리량(Estimated bytes billed)'을 반드시 확인하세요. 만약 이 숫자가 평소보다 비정상적으로 크다면(수십 GB ~ TB 단위), 파티셔닝 조건을 빼먹지 않았는지 쿼리를 멈추고 다시 점검하는 것이 좋습니다. 처음에는 번거로울 수 있지만, 이 작은 습관 하나가 회사의 리소스를 아끼고 1인분의 몫을 해내는 데이터 분석의 핵심 기본기입니다.


사진처럼 파티셔닝이 걸리면 6.74GB 약 60원 정도입니다. (대략 1TB는 만원 정도 입니다. 클래스101의 과금 체계 기준)

참고로 원본 테이블은 10TB정도로 풀스캔 시 10만원이 나갑니다.



심화

(아래는 제가 예전에 회사에 팀원분들께 공유드렸던 내용입니다. 좀 더 공부하시고 싶으신 분을 위해 남겨놓습니다. )


쿼리 비용 관련해서 가이드 문서를 읽어보니, 몇몇 좋은 포인트가 있어 공유합니다.


클러스터링


  1. 클러스터링과 파티션의관계는 사진과 같다.
  2. 클러스터링이 먹힌 열의 순서대로 where절에 작성해줘야, 잘 작동한다. (어느정도는 빅쿼리가 알아서쳐줌)
  3. CAST(customer_id AS STRING) = "10000"처럼 함수를 걸면 작동안한다. customer_id = 10000 처럼 심플하게 해야한다. 마찬가지로 datetime(timestamp) = XX 식으로 해도 클러스터링이 안먹는다.
  4. 클러스터링 열은 최대 4개만 지정할 수 있다.
  5. 클러스터링된 테이블을 사용하면 LIMIT 절이 스캔되는 바이트 수를 줄일 수 있습니다. 즉, 클러스터링 안걸린 경우에만 LIMIT이 작동안합니다. LIMIT 절을 사용합니다.


참고) JOIN할 때 기초적인 팁

  1. JOIN 할때에는 첫테이블이 가장 큰 테이블인게 좋다. (이게 이유가 있는데, 브로드캐스팅 어쩌구. [작은테이블 LEFT JOIN 큰테이블]하면 처리하기 힘들어합니다.
  2. Self Join 보다는 윈도우 함수 사용하기
  3. Cross join할 때는 미리 Group by 하고 사용하기





구글 공식문서

  1. 클러스터링 테이블 소개 : https://cloud.google.com/bigquery/docs/clustered-tables?hl=ko#block-pruning
  2. 쿼리 비용 관리 : https://cloud.google.com/bigquery/docs/best-practices-costs?utm_source=chatgpt.com&hl=ko



260
무료 공개
아직 작성된 댓글이 없어요