PREWHERE는 읽어야 하는 데이터 양을 줄여 필터링 효율을 높일 수 있습니다. 기본적으로 ClickHouse는 쿼리에서 PREWHERE를 명시적으로 지정하지 않아도 WHERE의 적합한 조건을 PREWHERE로 옮겨 이 최적화를 적용합니다. 이 단계에서 적용할 조건을 제어하려면 PREWHERE를 명시적으로 지정할 수 있습니다.
PREWHERE를 사용하면 ClickHouse는 먼저 조건 평가에 필요한 컬럼만 읽습니다. 그런 다음 일치하는 행이 하나 이상 포함된 블록에 대해서만 쿼리에 필요한 나머지 컬럼을 읽습니다. 조건에 사용되는 컬럼이 쿼리의 나머지 부분에서 사용하는 컬럼보다 적고 많은 블록이 필터링되는 경우, 읽어야 하는 데이터 양을 줄일 수 있습니다.
PREWHERE 수동 제어하기
PREWHERE를 수동으로 지정하십시오. 이렇게 하면 나머지 컬럼에서 읽는 데이터 양을 줄일 수 있습니다.
쿼리에는 PREWHERE와 WHERE를 모두 포함할 수 있습니다. 이 경우 PREWHERE가 먼저 평가됩니다.
ClickHouse가 조건을 WHERE에서 PREWHERE로 자동 이동하지 않도록 하려면 optimize_move_to_prewhere를 0으로 설정하십시오.
FINAL 수정자가 있는 쿼리에서는 optimize_move_to_prewhere와 optimize_move_to_prewhere_if_final가 모두 활성화된 경우에만 ClickHouse가 조건을 WHERE에서 PREWHERE로 이동합니다.
기본적으로
PREWHERE는 FINAL보다 먼저 평가됩니다. 따라서 PREWHERE가 테이블의 ORDER BY 키에 포함되지 않은 컬럼을 참조하면 FROM ... FINAL 쿼리에서 예기치 않은 결과가 발생할 수 있습니다.JOIN에서의 PREWHERE
JOIN이 포함된 쿼리에서 PREWHERE 조건은 최대 하나의 테이블의 컬럼만 직접 참조할 수 있습니다. ClickHouse는 조인에 도달하기 전에 해당 테이블의 행에 이 조건을 적용합니다.
반면 WHERE 조건은 논리적으로 조인된 결과를 필터링합니다. 다만 결과가 달라지지 않는다면 최적화기가 조인 전에 조건을 적용할 수 있습니다. 따라서 동일한 조건을 PREWHERE와 WHERE에 사용하면, 특히 외부 조인에서는 서로 다른 결과가 나올 수 있습니다.
다음 예시에서는 이러한 차이를 보여 주기 위해 두 개의 테이블을 생성합니다:
PREWHERE가 LEFT JOIN 전에 table_2를 필터링하므로, id = 1인 table_1의 행은 일치하는 행 없이 남습니다:
WHERE에서 동일한 조건을 사용하면 JOIN 결과가 필터링되어 id = 1인 행이 제거됩니다:
제한 사항
PREWHERE는 *MergeTree 계열 테이블에서만 지원됩니다.