프로그래밍백엔드 개발자

WITH (공통 테이블 표현식, CTE)의 지시문은 무엇을 합니까? CTE를 서브쿼리와 비교할 때의 장점은 무엇입니까? 예를 들어 주십시오.

Hintsage AI 어시스턴트로 면접 통과

답변

WITH 지시문 (또는 CTE — 공통 테이블 표현식)은 주 SELECT에서 사용하거나 재귀적으로 사용할 수 있는 결과 집합을 임시로 생성합니다. CTE는 쿼리를 이해하기 쉽게 하고 가독성을 높이며 중간 결과를 재사용할 수 있게 합니다.

일반 서브쿼리와의 장점:

  • 복잡한 쿼리의 가독성을 향상시킵니다 (디버깅 및 유지 관리가 더 쉬움).
  • 재귀 쿼리를 사용할 수 있습니다.
  • 동일한 서브쿼리를 중복하는 대신 이름으로 여러 번 CTE에 접근할 수 있습니다.

예:

WITH high_salary AS ( SELECT id, name FROM employees WHERE salary > 100000 ) SELECT * FROM high_salary WHERE name LIKE 'A%';

함정 질문

“CTE 선언 시 MATERIALIZED/NOT MATERIALIZED를 명시하는 것이 중요한가요? 이것이 성능에 어떤 영향을 미칠 수 있나요?”

답변: PostgreSQL에서는 MATERIALIZED (CTE를 한 번 계산하고 저장, 여러 번 사용하더라도) 또는 NOT MATERIALIZED (CTE가 주 쿼리에 인라인됨)를 명시할 수 있습니다. 일반적으로 최적화기가 CTE를 물질화할지를 스스로 결정하지만, 강제로 명시하는 것이 성능에 상당한 영향을 미칠 수 있습니다.

예:

WITH high_salary AS MATERIALIZED ( SELECT id, name FROM employees WHERE salary > 100000 ) SELECT * FROM high_salary WHERE name LIKE 'A%';

역사

한 대규모 프로젝트에서 분석가는 모든 서브쿼리를 CTE로 대체했지만, PostgreSQL이 12 이전 버전에서는 CTE가 항상 물질화된다는 것을 몰랐습니다. 그 결과로 쿼리가 2-3배 느려졌습니다. 서브쿼리로 돌아가거나 새로운 버전으로 전환한 후 문제가 해결되었습니다.


역사

여러 수준의 중첩 서브쿼리로 작성된 보고서는 동료에게 읽기 어려운 결과를 초래했습니다. 의미 있는 이름을 가진 CTE로 다시 작성하니, 쿼리를 논의하고 지원하는 것이 상당히 쉬워졌습니다.


역사

동일한 이름의 두 CTE가 큰 스크립트에서 혼란을 일으켰습니다: CTE가 선언되기 전에도 사용되었기 때문입니다. 결과적으로 컴파일 오류와 문제의 원인을 찾는 데 많은 시간을 소모했습니다.