쿼리 처리 구성 요소 식별

완료됨

쿼리를 실행하는 데는 4개의 개별 단계가 있습니다. 실행 순서에 따라 이러한 단계는 다음과 같습니다.

  1. 구문 분석
  2. 변환(재작성)
  3. 계획 수립
  4. 실행

파서

파서는 쿼리 문자열에서 유효한 구문을 확인하는 역할을 담당합니다. 파서에는 다음 두 가지 주요 부분이 있습니다.

  • 문법 규칙 및 해당 작업 집합으로 구성된 gram.y입니다.
  • scan.1 식별자와 SQL 키워드를 인식하는 렉서입니다. 모든 키워드 또는 식별자는 생성되고 파서에 전달되는 토큰을 트리거합니다.

파서는 쿼리 트리를 작성하여 쿼리를 식별 가능한 부분으로 구분하여 관련된 테이블, 적용된 필터 등을 파악합니다. 쿼리 트리의 부분은 다음과 같습니다.

  • 명령 유형 - SELECT, INSERT, UPDATE 또는 DELETE입니다.
  • RTE(범위 테이블 항목) - 관계, 테이블, ie 하위 쿼리, 조인 결과 등의 목록입니다. SELECT 문에서 이러한 항목은 FROM 키 단어 뒤에 나타납니다.
  • 결과 관계 - INSERT, UPDATE 및 DELETE 명령의 결과 관계는 변경 내용을 적용할 테이블 또는 뷰입니다.
  • 대상 목록 - SELECT와 FROM 키워드 사이에서 식별되는 쿼리의 결과입니다. DELETE 명령은 결과를 생성하지 않으므로 Planner는 실행기가 삭제할 행을 찾을 수 있도록 특수 항목을 추가합니다. INSERT 명령은 결과 관계로 이동해야 하는 새 행을 식별합니다. UPDATE 명령의 경우 대상 목록에서 이전 행을 대체해야 하는 새 행을 설명합니다.
  • Qualification - 최종 결과 행에 대한 작업을 실행할지 여부를 지정하는 부울 값입니다. SQL 문의 WHERE 절에 해당합니다.
  • 조인 트리 - 이 트리는 FROM 항목의 목록일 수 있습니다. 조인은 순서에 관계없이 수행하거나 외부 조인과 같은 특정 순서로 수행할 수 있습니다.
  • 기타 - ORDER BY 절과 같이 이 단계에서 관련이 없는 항목입니다.

재작성기

오류 메시지가 반환되는 경우 오류가 발견되지 않는 한 파서의 출력은 변환 또는 재작성 프로세스에 전달됩니다.

쿼리 재작성은 규칙을 적용하여 쿼리 텍스트를 다시 작성합니다. 재작성기는 규칙을 고려한 다음, 수정된 쿼리를 쿼리 플래너에 전달합니다. 행 수준 보안은 이 단계에서 구현됩니다.

예를 들어 SELECT에 대한 규칙은 INSERT, UPDATE 및 DELETE 쿼리를 포함하여 항상 마지막 단계로 적용됩니다. 또한 규칙은 UPDATE 쿼리가 기존 행을 덮어쓰지 않고 새 행이 삽입되고 이전 행이 숨겨져 있음을 의미합니다. 트랜잭션이 커밋된 후에는 진공 프로세스에서 숨겨진 행을 제거할 수 있습니다.

계획자

Planner의 작업은 쿼리 규칙을 사용하고 쿼리를 실행할 수 있는 다양한 방법 중 가장 빠른 방법을 이해하는 것입니다.

Planner는 데이터에 대한 실제 작업을 나타내는 노드를 사용하여 계획 트리를 만듭니다.

PostgreSQL은 비용 기반 쿼리 최적화 관리자를 사용하여 쿼리에 대한 최적의 계획을 찾습니다. Planner는 다양한 실행 계획을 평가하고 CPU 주기, I/O 작업 등 필요한 리소스의 양을 예측합니다. 이 예상치는 계획 비용이라고 하는 단위로 변환됩니다. 비용이 가장 낮은 플랜이 선택됩니다.

그러나 조인 수가 증가함에 따라 가능한 계획의 수는 기하급수적으로 증가합니다. 비교적 간단한 쿼리에서도 가능한 모든 계획을 평가하는 것은 불가능해집니다. 추론 및 알고리즘은 가능한 계획의 수를 제한하는 데 사용됩니다. 그 결과 선택한 계획이 최적 계획이 아닐 수 있습니다. 그러나 거의 최적에 가깝고 적절한 시간에 선택됩니다.

비용은 플래너의 가장 좋은 추정치입니다. 비용 예측의 목적은 동일한 조건에서 동일한 쿼리에 대한 다른 실행 계획을 비교하는 것입니다. Planner는 테이블 및 행에서 수집된 통계를 사용하여 쿼리에 대한 예상 비용을 생성합니다. 비용 예측이 정확하려면 통계가 최신 상태여야 합니다.

최신 통계

쿼리 최적화 프로그램의 Planner 구성 요소는 테이블 및 행에 대한 통계를 사용하여 정확한 예상 비용을 생성합니다.

ANALYZE는 데이터베이스 테이블에 대한 통계를 수집하고 결과를 pg_statistic 시스템 카탈로그에 저장합니다. 다음 경우 ANALYZE를 실행해야 합니다.

  • 자동 진공을 사용하지 않도록 설정했습니다(일반적으로 테이블을 자동으로 분석).
  • 자동 진공을 사용하지 않도록 설정했으며 최근에 ANALYZE를 실행하지 않았습니다.
  • 앞에 것 중 하나이며, INSERTS, UPDATES 또는 DELETE 문이 많이 있습니다.

비용 예측은 최신 통계에 의존합니다. 그러나 통계가 최신이 아닐 경우, 비효율적인 계획이 선택될 수 있습니다. ANALYZE에 매개 변수가 전달되지 않으면 데이터베이스의 모든 테이블이 검사됩니다.

ANALYZE 구문은 다음과 같습니다.

ANALYZE [ VERBOSE ] [ ***table*** [ ( ***column*** [, ...] ) ] ]

VERBOSE는 일부 통계와 함께 분석 중인 테이블을 표시하는 진행률 메시지를 표시합니다.

사용량이 적은 시간 동안 매일 실행되도록 VACUUM 및 ANALYZE를 예약합니다. ANALYZE는 대상 테이블에 대한 읽기 잠금만 필요하므로 다른 작업과 병렬로 실행할 수 있습니다.

Executor

이 단계에서는 Planner가 만든 계획을 취하고 재귀적으로 처리하여 필요한 행 집합을 추출합니다. 계획 노드를 호출할 때마다 실행기는 행을 전달하거나 완료되었음을 다시 보고해야 합니다.

실행기는 네 가지 SQL 쿼리 형식을 모두 평가합니다.

  • SELECT
  • INSERT
  • 업데이트
  • 삭제

SELECT의 경우 실행기는 각 행을 결과 집합으로 클라이언트에 다시 반환합니다.

INSERT의 경우 반환된 각 행이 지정된 테이블에 삽입됩니다. 이 작업은 ModifyTable이라는 특수한 최상위 계획 노드에서 수행됩니다.

UPDATE의 경우 계산된 각 행에는 업데이트된 모든 열 값과 대상 행의 행 ID가 포함됩니다. 데이터는 업데이트된 행을 만들고 이전 행을 삭제된 것으로 표시하는 ModifyTable 노드로 전송됩니다.

DELETE의 경우 계획에서 반환되는 유일한 열은 행 ID입니다. ModifyTable 노드는 행 ID를 사용하여 행을 삭제된 것으로 표시합니다.