쿼리의 경로
쿼리의 경로 (The Path of a Query)
여러분이 날린 SQL 쿼리가 PostgreSQL 내부에서 어떤 단계를 거쳐 결과로 돌아오는지 궁금한 적 있죠? 여기서 쿼리가 결과를 얻기까지 통과해야 하는 단계들을 한눈에 보여드릴게요. 내부 구조를 이해하면 옵티마이저가 왜 이런 실행 계획을 세우는지 훨씬 자연스럽게 읽힙니다.
출처: 공식문서
1단계: 연결
애플리케이션 프로그램에서 PostgreSQL 서버로의 연결이 먼저 확립되어야 해요. 애플리케이션은 쿼리를 서버로 전송하고, 서버가 돌려보내는 결과를 받을 때까지 기다려요.
2단계: 파서 (parser)
파서(parser) 단계는 애플리케이션이 보낸 쿼리가 문법적으로 올바른지 검사하고, **쿼리 트리(query tree)**를 만들어요.
3단계: 재작성 시스템 (rewrite system)
**재작성 시스템(rewrite system)**은 파서 단계가 만든 쿼리 트리를 받아서, 시스템 카탈로그(system catalogs)에 저장된 규칙(rules) 중 그 쿼리 트리에 적용할 것이 있는지 찾아요. 규칙 본문에 주어진 변환을 수행하죠.
재작성 시스템의 한 응용이 **뷰(view)**의 실현이에요. 뷰(즉 가상 테이블)에 대한 쿼리가 만들어질 때마다, 재작성 시스템은 사용자의 쿼리를 뷰 정의에 주어진 **기본 테이블(base tables)**에 접근하는 쿼리로 다시 써요.
4단계: 플래너/옵티마이저 (planner/optimizer)
**플래너/옵티마이저(planner/optimizer)**는 (재작성된) 쿼리 트리를 받아서, **실행기(executor)**의 입력이 될 **쿼리 계획(query plan)**을 만들어요.
먼저 같은 결과로 이끄는 가능한 모든 **경로(path)**를 만들어요. 예를 들어 스캔할 릴레이션에 인덱스가 있으면 스캔에는 두 가지 경로가 있어요. 하나는 단순 순차 스캔(sequential scan)이고, 다른 하나는 인덱스를 쓰는 거예요. 다음으로 각 경로의 실행 비용을 추정하고 가장 저렴한 경로를 골라요. 가장 저렴한 경로는 실행기가 쓸 수 있는 완전한 계획으로 확장돼요.
5단계: 실행기 (executor)
**실행기(executor)**는 계획 트리를 재귀적으로 따라가며, 계획이 나타내는 방식대로 행을 검색해요. 릴레이션을 스캔할 때 **저장 시스템(storage system)**을 이용하고, **정렬(sort)**과 **조인(join)**을 수행하며, **조건(qualification)**을 평가하고, 마지막으로 유도된 행들을 돌려줘요.
다음 절들에서는 위 각 항목을 더 자세히 다뤄서 PostgreSQL의 내부 제어·데이터 구조를 이해하는 데 도움을 줄게요.