[PostgreSQL] 두 컬럼이 서로 얽혀 있으면 플래너는 수백 배 틀린다

지난 편은 컬럼 하나의 통계가 틀리는 경우였다. 이번 편은 컬럼 하나하나는 정확한데 함께 쓰면 틀리는 경우다. 이쪽이 더 자주, 더 크게 빗나간다. 독립 가정 주소 테이블이 있다. sido(시도)와 sigungu(시군구) 컬럼이 있다. SELECT * FROM addresses WHERE sido = '서울특별시' AND sigungu = '강남구'; 플래너는 이렇게 계산한다. sido = '서울특별시'인 비율: 최빈값 목록에서 찾음. 20%라고 하자. sigungu = '강남구'인 비율: 최빈값 목록에서 찾음. 2%라고 하자. 둘 다 만족하는 비율: 20% × 2% = 0.4% 그런데 강남구는 서울에만 있다. sigungu = '강남구'인 행은 전부 sido = '서울특별시'다. 실제 비율은 2%다. 플래너는 5배 적게 추정했다. ...

9월 20, 2026 · Jun Kang

[PostgreSQL] 플래너는 통계를 보고 결정한다 — 그 통계는 언제 틀리나

EXPLAIN ANALYZE를 보면 두 숫자가 나란히 있다. rows=100과 actual rows=1500000. 플래너는 백 행이 나올 줄 알고 계획을 짰는데 실제로는 백오십만 행이 나왔다. 그 계획은 백 행에 맞는 계획이었을 테니, 결과는 느린 쿼리다. 플래너가 왜 백 행이라고 생각했는지를 따라가면 통계에 닿는다. 이 시리즈는 그 통계 이야기다. 통계는 표본이다 플래너는 실행 전에 테이블을 읽지 않는다. ANALYZE가 미리 만들어둔 요약을 본다. ANALYZE는 테이블 전체를 읽지 않는다. 표본을 뽑는다. 표본 크기는 default_statistics_target × 300이고, 기본값이 100이라 3만 행이다. 테이블이 천 행이든 십억 행이든 3만 행이다. ...

9월 19, 2026 · Jun Kang

전환이 희소한 서비스에서 A/B 테스트하기

제품 실험을 주 단위로 돌려보려다 첫 주에 막혔다. 판정할 지표가 없었다. 있긴 한데 쓸 수가 없었다. 우리가 궁극적으로 올리고 싶은 건 결제인데, 결제는 주 단위로 보면 건수가 너무 적어서 어떤 변화를 줘도 통계적으로 구분이 안 된다. 이 문제를 어떻게 우회했는지, 그리고 그 과정에서 밟은 함정들을 정리해둔다. 회사마다 숫자는 다르겠지만 구조는 비슷할 것 같다. 왜 최종 전환으로는 판정할 수 없나 필요한 표본 수는 대략 이 식을 따른다. 유의수준 5%(양측), 검정력 80% 기준이다. ...

9월 9, 2026 · Jun Kang