ClickHouse SELECT

ClickHouse SELECT (SELECT)

SELECT 쿼리는 데이터를 조회하는 데 사용해요. 기본적으로 요청한 데이터를 클라이언트에 돌려주고, INSERT INTO와 함께 쓰면 다른 테이블로 전달할 수도 있어요.

쿼리는 여러 절을 조합해서 구성해요. SELECT 바로 뒤의 표현식 목록은 필수이고, 나머지 절은 선택이에요.

출처: https://clickhouse.com/docs/sql-reference/statements/select

기본 문법

[WITH expr_list(subquery)]
SELECT [DISTINCT [ON (...)] expr_list]
[FROM [db.]table] [FINAL]
[SAMPLE sample_coeff]
[ARRAY JOIN ...]
[JOIN ...]
[PREWHERE expr]
[WHERE expr]
[GROUP BY expr_list] [WITH ROLLUP|WITH CUBE] [WITH TOTALS]
[HAVING expr]
[WINDOW window_expr_list]
[QUALIFY expr]
[ORDER BY expr_list] [WITH FILL]
[LIMIT [offset_value, ]n BY columns]
[LIMIT [n, ]m] [WITH TIES]
[SETTINGS ...]
[UNION ...]
[INTO OUTFILE filename]
[FORMAT format]

주요 절

  • WITH — 서브쿼리나 표현식에 이름(CTE)을 붙여 재사용.
  • DISTINCT — 중복 행 제거. DISTINCT ON (col1, ...)로 특정 컬럼 기준.
  • FROM — 데이터 소스(테이블, 서브쿼리, 테이블 함수). FINAL은 MergeTree 패밀리에서 모든 파트를 완전히 병합한 결과를 읽어요.
  • SAMPLE — 표본 추출. SAMPLE 0.1.
  • ARRAY JOIN — 배열 컬럼을 행으로 펼치기.
  • JOIN — 테이블 조인. GLOBAL/ANY/ALL/ASOF/INNER/LEFT/RIGHT/FULL/CROSS/OUTER/SEMI/ANTI.
  • PREWHEREWHERE보다 먼저 적용하는 최적화용 필터.
  • WHERE — 행 필터.
  • GROUP BY — 그룹화. WITH ROLLUP / CUBE / TOTALS.
  • HAVING — 그룹 결과 필터.
  • QUALIFY — 윈도우 함수 결과로 필터.
  • ORDER BY — 정렬. WITH FILL로 빈 값 채우기.
  • LIMIT BY — 그룹별 행 수 제한.
  • LIMIT — 결과 행 제한. WITH TIES.
  • SETTINGS — 쿼리 단위 설정.
  • UNION / INTERSECT / EXCEPT — 집합 연산.
  • FORMAT — 출력 포맷 지정.

쿼리는 파이프 연산자로도 선형 체인처럼 쓸 수 있어요.

FROM table
|> WHERE x > 1
|> AGGREGATE count() AS c GROUP BY y
|> ORDER BY c DESC

SELECT 절

SELECT 절의 표현식은 위 절들이 처리된 뒤 계산돼요.

  • 모든 컬럼: SELECT * FROM ....
  • 동적 컬럼 선택: COLUMNS('regexp')로 정규식에 맞는 컬럼 선택. 예: SELECT COLUMNS('a') FROM col_names.
  • * LIKE / * ILIKE — 컬럼 이름을 LIKE 패턴으로 매칭. 예: SELECT * ILIKE 'a%' FROM col_names.
SELECT COLUMNS('a') FROM col_names
┌─aa─┬─ab─┐
│  1 │  1 │
└────┴────┘
  • 애스터리스크(*)는 MATERIALIZED·ALIAS 컬럼을 제외한 모든 컬럼으로 확장돼요. 컬럼이 적을 때나 PREWHERE 필터가 강할 때만 쓰는 걸 권장하고, 일반적으로는 쓰지 않는 게 좋아요.

구현 상세

DISTINCT, GROUP BY, ORDER BY, 서브쿼리가 없으면 쿼리는 완전히 스트림 처리되며 O(1) RAM을 사용해요. 그렇지 않으면 아래 제한 설정으로 메모리를 관리해야 해요.

  • max_memory_usage
  • max_rows_to_group_by
  • max_rows_to_sort
  • max_rows_in_distinct / max_bytes_in_distinct
  • max_rows_in_set / max_bytes_in_set
  • max_rows_in_join / max_bytes_in_join
  • max_bytes_before_external_sort
  • max_bytes_before_external_group_by

외부 정렬(임시 테이블을 디스크에 저장)과 외부 집계도 가능해요.

SELECT 수정자

  • APPLY — 외부 테이블 표현식의 각 행에 함수 적용.
  • EXCEPT — 결과에서 특정 컬럼 제외.
  • REPLACESELECT *의 컬럼을 표현식으로 교체.
SELECT COLUMNS('[jk]') APPLY(toString) APPLY(length) APPLY(max) FROM columns_transformers;
SELECT * REPLACE(i + 1 AS i) EXCEPT (j) APPLY(sum) from columns_transformers;

SETTINGS

쿼리 안에서 바로 설정을 지정할 수 있어요. 이 설정은 해당 쿼리에만 적용되고, 실행 후 기본값으로 되돌아가요.

SELECT * FROM some_table SETTINGS optimize_read_in_order=1, cast_keep_nullable=1;

더 알아보기