일반 뷰
매개변수화된 뷰(Parameterized View)
Materialized View
OR REPLACE와 IF NOT EXISTS는 서로 배타적이므로 함께 사용할 수 없습니다. 둘을 함께 사용하면 구문 오류가 발생합니다.
CREATE OR REPLACE MATERIALIZED VIEW
CREATE OR REPLACE MATERIALIZED VIEW는 기존 materialized view와 해당 내부 저장 테이블(있는 경우)을 원자적으로 대체합니다. 이 작업을 수행하려면 Atomic 또는 Replicated 데이터베이스 엔진이 필요합니다.
TO절 없이: 기존 내부 테이블이 삭제되고 새 테이블이 생성됩니다.POPULATE를 지정하지 않으면 내부 테이블의 기존 데이터는 손실됩니다.TO절 사용 시: 뷰 정의만 대체되며 대상 테이블과 그 데이터에는 영향이 없습니다.REFRESH,ON CLUSTER, 그리고 모든 엔진 옵션과 호환됩니다.POPULATE는Atomic데이터베이스에서만 지원되며,Replicated데이터베이스에서는 허용되지 않습니다(아래POPULATE참고 사항 참조).CREATE VIEW및DROP VIEW권한이 필요합니다.
CREATE OR REPLACE MATERIALIZED VIEW는 Atomic 또는 Replicated 데이터베이스 엔진에서만 지원됩니다. Ordinary 데이터베이스 엔진에서는 지원되지 않습니다.TO [db].[table] 없이 materialized view를 생성할 때는 데이터를 저장할 테이블 엔진인 ENGINE을 지정해야 합니다.
TO [db].[table]과 함께 materialized view를 생성할 때는 POPULATE를 함께 사용할 수 없습니다.
materialized view는 다음과 같이 동작합니다. SELECT에 지정된 테이블에 데이터를 삽입하면, 삽입된 데이터의 일부가 이 SELECT 쿼리로 변환되고 그 결과가 뷰에 삽입됩니다.
ClickHouse의 materialized view는 대상 테이블에 삽입할 때 컬럼 순서가 아니라 컬럼 이름을 사용합니다. 일부 컬럼 이름이
SELECT 쿼리 결과에 없으면, 해당 컬럼이 널 허용이 아니더라도 ClickHouse는 기본값을 사용합니다. materialized view를 사용할 때는 모든 컬럼에 별칭을 추가하는 것이 안전합니다.ClickHouse의 materialized view는 삽입 트리거에 더 가깝게 구현됩니다. 뷰 쿼리에 집계가 포함된 경우, 집계는 새로 삽입된 데이터 배치에만 적용됩니다. 원본 테이블의 기존 데이터에 대한 변경(예: 업데이트, 삭제, 파티션 삭제 등)은 materialized view에 반영되지 않습니다.ClickHouse의 materialized view는 오류 발생 시 결정적 동작을 보장하지 않습니다. 즉, 이미 기록된 블록은 대상 테이블에 유지되지만, 오류 이후의 모든 블록은 유지되지 않습니다.기본적으로 뷰 중 하나에 푸시하는 과정에서 예외가 발생하면 INSERT 쿼리가 실패합니다. 그 시점까지 블록이 이미 원본 테이블에 도달했는지는 보장되지 않습니다. 이는 뷰 오류가 아니라 삽입 파이프라인의 타이밍에 따라 달라집니다. 원본 테이블과 모든 종속 뷰에 대해 exactly-once 전달을 보장하려면, 삽입 중복 제거(insert_deduplicate, deduplicate_blocks_in_dependent_materialized_views)를 사용하여 실패한 INSERT을 다시 시도하십시오.INSERT 쿼리에서 materialized_views_ignore_errors=true를 설정하면 오류 보고 방식만 바뀝니다. 각 뷰 오류는 경고로 기록되고 INSERT 쿼리는 성공합니다. 오류가 발생한 뷰의 대상에 대한 전달은 부분적으로만 이루어집니다. 예외가 발생하기 전에 처리된 블록은 유지되고, 오류가 발생한 블록과 그 이후의 모든 블록은 해당 뷰에서 삭제됩니다. 해당 대상의 다운스트림 뷰는 실제로 도착한 블록만 보게 되므로, 이들에 대한 전달도 부분적으로만 이루어집니다. 오류를 발생시키지 않은 형제 뷰(및 그 다운스트림 체인)에는 전체가 기록되며, 원본 테이블도 평소처럼 기록됩니다. INSERT가 성공으로 보고되므로 클라이언트는 실패 신호를 받지 못하고 자동 재시도도 트리거되지 않습니다. 따라서 이 설정은 원본 테이블 쓰기가 뷰 측 문제로 차단되면 안 되는 경우(예: system.*_log 테이블)에만 사용하십시오.materialized_views_ignore_errors는 system.*_log 테이블에서 기본적으로 true입니다.POPULATE를 지정하면, 뷰를 생성할 때 기존 테이블 데이터가 마치 CREATE TABLE ... AS SELECT ...를 수행하는 것처럼 뷰에 삽입됩니다. 그렇지 않으면 쿼리에는 뷰를 생성한 이후 테이블에 삽입된 데이터만 포함됩니다. 뷰 생성 중에 테이블에 삽입된 데이터는 뷰에 삽입되지 않으므로 POPULATE 사용은 권장하지 않습니다.
POPULATE는 CREATE TABLE ... AS SELECT ...처럼 동작하므로 다음과 같은 제한이 있습니다.- 복제된 데이터베이스에서는 지원되지 않습니다
- ClickHouse Cloud에서는 지원되지 않습니다
INSERT ... SELECT를 사용할 수 있습니다.SELECT 쿼리에는 DISTINCT, GROUP BY, ORDER BY, LIMIT를 포함할 수 있습니다. 해당 변환은 삽입된 데이터의 각 블록에서 서로 독립적으로 수행된다는 점에 유의하십시오. 예를 들어 GROUP BY가 설정된 경우 데이터는 삽입 중에 집계되지만, 이는 삽입된 데이터의 단일 패킷 내에서만 수행됩니다. 이후에는 데이터가 추가로 집계되지 않습니다. 예외적으로 SummingMergeTree처럼 자체적으로 데이터 집계를 수행하는 ENGINE을 사용할 때는 다릅니다.
materialized view가 TO [db.]name 구문을 사용하는 경우, 뷰를 DETACH하고 대상 테이블에 ALTER를 실행한 다음, 앞서 분리한(DETACH) 뷰를 ATTACH할 수 있습니다.
materialized view는 optimize_on_insert 설정의 영향을 받는다는 점에 유의하십시오. 데이터는 뷰에 삽입되기 전에 머지됩니다.
뷰는 일반 테이블과 동일하게 표시됩니다. 예를 들어 SHOW TABLES 쿼리 결과에 나열됩니다.
뷰를 삭제하려면 DROP VIEW를 사용하십시오. DROP TABLE도 VIEW에 사용할 수 있습니다.
SQL 보안
DEFINER 및 SQL SECURITY를 사용하면 뷰의 기반 쿼리를 실행할 때 어떤 ClickHouse 사용자를 사용할지 지정할 수 있습니다.
SQL SECURITY에는 DEFINER, INVOKER, NONE의 세 가지 유효한 값이 있습니다. DEFINER 절에는 기존 사용자 또는 CURRENT_USER를 지정할 수 있습니다.
다음 표는 뷰에서 SELECT할 때 어떤 사용자에게 어떤 권한이 필요한지 설명합니다.
SQL 보안 옵션과 관계없이, 어떤 경우에도 뷰를 읽으려면 여전히 GRANT SELECT ON <view> 권한이 필요합니다.
| SQL security option | View | Materialized View |
|---|---|---|
DEFINER alice | alice는 뷰의 소스 테이블에 대한 SELECT 권한이 있어야 합니다. | alice는 뷰의 소스 테이블에 대한 SELECT 권한과 뷰의 대상 테이블에 대한 INSERT 권한이 있어야 합니다. |
INVOKER | 사용자는 뷰의 소스 테이블에 대한 SELECT 권한이 있어야 합니다. | materialized view에는 SQL SECURITY INVOKER를 지정할 수 없습니다. |
NONE | - | - |
SQL SECURITY NONE은 더 이상 권장되지 않는 옵션입니다. SQL SECURITY NONE으로 뷰를 생성할 수 있는 권한이 있는 사용자는 임의의 쿼리를 실행할 수 있습니다.
따라서 이 옵션으로 뷰를 생성하려면 GRANT ALLOW SQL SECURITY NONE TO <user> 권한이 필요합니다.DEFINER/SQL SECURITY를 지정하지 않으면 기본값이 사용됩니다:
SQL SECURITY: 일반 뷰에는INVOKER, materialized view에는DEFINER(설정으로 구성 가능)DEFINER:CURRENT_USER(설정으로 구성 가능)
DEFINER/SQL SECURITY를 지정하지 않고 뷰를 ATTACH하면, materialized view의 기본값은 SQL SECURITY NONE이고 일반 뷰의 기본값은 SQL SECURITY INVOKER입니다.
기존 뷰의 SQL 보안을 변경하려면 다음을 사용합니다:
예시
라이브 view
갱신 가능 구체화 뷰
interval은 단순한 인터벌의 연속입니다:
REFRESH 절에는 EVERY, AFTER, DEPENDS ON 중 적어도 하나를 지정해야 합니다. 이들 없이 단독으로 사용하는 REFRESH는 허용되지 않습니다. EVERY/AFTER 없이 사용하는 REFRESH DEPENDS ON ...는 REFRESH AFTER 0 SECOND DEPENDS ON ...의 축약형입니다. 자세한 내용은 아래의 갱신 의존성을 참조하십시오.
해당 쿼리를 주기적으로 실행하고 결과를 테이블에 저장합니다.
APPEND를 지정하면 각 갱신 시 기존 행을 삭제하지 않고 테이블에 행을 삽입합니다. 이 삽입은 일반적인INSERT INTO ... SELECT쿼리와 마찬가지로 원자적이지 않습니다.- 그렇지 않으면 각 갱신 시 테이블의 이전 내용이 원자적으로 대체됩니다.
- 삽입 트리거가 없습니다.
SELECT에 지정된 테이블에 새 데이터가 삽입되어도 갱신 가능 구체화 뷰로 자동 반영되지 않습니다. 대신 데이터 삽입은 주기적 또는 수동 갱신 실행 중에만 이루어집니다. SELECT쿼리에는 제한이 없습니다. 테이블 함수(예:url()), 뷰, UNION, JOIN을 모두 사용할 수 있습니다.
쿼리의
REFRESH ... SETTINGS 부분에 있는 설정은 갱신 설정(예: refresh_retries)이며, 일반 설정(예: max_threads)과는 구분됩니다. 일반 설정은 쿼리 끝에 SETTINGS를 사용해 지정할 수 있습니다.갱신 일정
RANDOMIZE FOR는 각 갱신 시각을 무작위로 조정합니다. 예:
REFRESH EVERY 1 MINUTE가 설정된 뷰의 갱신에 2분이 걸리면, 실제로는 2분마다 갱신됩니다. 이후 속도가 빨라져 10초 만에 갱신을 마치게 되면, 다시 1분마다 갱신됩니다. (즉, 누락된 갱신을 따라잡기 위해 10초마다 갱신되지는 않습니다. 그런 식의 밀린 갱신은 존재하지 않습니다.)
일반적으로 첫 번째 갱신은 materialized view가 생성된 직후 즉시 시작됩니다. 마지막 갱신 이후 경과 시간은 무한대이므로, 어떤 일정이든 지금 갱신할 시점으로 간주됩니다. EMPTY를 지정하면 이 초기 갱신은 건너뛰고, 첫 번째 갱신은 다음 예약된 시각에 수행됩니다. 예를 들어 EVERY 1 HOUR의 경우 첫 번째 갱신은 현재 시간의 끝에 수행됩니다.
복제된 DB에서
APPEND 모드에서는 SETTINGS all_replicas = 1을 사용해 coordination을 비활성화할 수 있습니다. 이렇게 하면 각 레플리카가 서로 독립적으로 갱신을 수행합니다. 이 경우 ReplicatedMergeTree는 필요하지 않습니다.
APPEND가 아닌 모드에서는 coordination된 갱신만 지원됩니다. coordination되지 않은 방식을 사용하려면 Atomic 데이터베이스와 CREATE ... ON CLUSTER 쿼리를 사용해 모든 레플리카에 갱신 가능 구체화 뷰를 생성하십시오.
coordination은 Keeper를 통해 수행됩니다. znode 경로는 default_replica_path 서버 설정으로 결정됩니다.
갱신 의존성
DEPENDS ON은 서로 다른 테이블의 갱신 시점을 동기화합니다:
DEPENDS ON은 갱신 가능 구체화 뷰(Refreshable Materialized View) 사이에서만 작동합니다. 특히 의존성 뷰에서 TO <table>을 사용하는 경우에는 테이블 이름이 아니라 뷰 이름을 사용해야 합니다. DEPENDS ON 목록에 일반 테이블, 갱신 가능하지 않은 뷰가 포함되어 있거나 오타가 있으면 해당 뷰는 갱신되지 않으며, system.view_refreshes에 상태가 MissingDependencies로 표시됩니다. 의존성은 ALTER를 사용해 변경하거나 제거할 수 있습니다. 자세한 내용은 갱신 매개변수 변경을 참조하십시오.일관된 전파 지연 시간을 위해 DEPENDS ON 사용
REFRESH EVERY를 사용하면 의존성은 각 타임슬롯마다 적용됩니다.
예를 들어 뷰 X와 Y가 모두 REFRESH EVERY 1 HOUR를 사용하고, Y가 X의 출력 테이블을 읽는다고 가정하겠습니다. 의존성이 없으면 Y는 일반적으로 X의 이전 시간 갱신 데이터만 보게 됩니다. DEPENDS ON X를 사용하면 Y의 11:00 갱신은 X의 11:00 갱신이 완료된 후에만 시작됩니다.
배치 스트림 처리에 DEPENDS ON 사용하기
REFRESH EVERY를 사용하지 않으면, 의존하는 뷰 X는 X가 마지막으로 갱신된 이후 모든 의존성이 각각 최소 한 번씩 갱신되었을 때 갱신됩니다. REFRESH AFTER T는 지연 시간을 추가합니다. 즉, 의존성이 갱신을 완료한 후 T 시간이 지나면 의존하는 뷰의 갱신이 시작됩니다.
순환 의존성은 허용되며 유용하게 활용할 수 있습니다. 다음 갱신 가능 구체화 뷰 그래프를 살펴보십시오:
- X는 어떤 스트림에서 행 배치를 가져와 테이블(table)에 저장합니다.
- 그런 다음 Y와 Z는 모두 해당 테이블을 읽고, 서로 다른 집계를 수행한 후 결과를 다른 테이블에 추가합니다.
- 배치가 완전히 처리되면 X는 다음 배치를 가져오고, 이 사이클이 반복됩니다.
SYSTEM REFRESH VIEW를 실행해야 합니다.
갱신 설정
refresh_retries- 갱신 쿼리가 예외로 실패한 경우 재시도할 횟수입니다. 모든 재시도가 실패하면 다음으로 예약된 갱신 시각으로 넘어갑니다. 0은 재시도하지 않음을, -1은 무한 재시도를 의미합니다. 기본값: 2.refresh_retry_initial_backoff_ms-refresh_retries가 0이 아닐 때 첫 번째 재시도 전까지의 지연 시간입니다. 이후 각 재시도마다 지연 시간이 두 배로 증가하며, 최대refresh_retry_max_backoff_ms까지 늘어납니다. 기본값: 100 ms.refresh_retry_max_backoff_ms- 갱신 시도 사이의 지연 시간이 지수적으로 증가할 때의 상한입니다. 기본값: 60000 ms(1분).all_replicas-APPEND를 사용하는 복제된 데이터베이스에서 모든 레플리카가 각각 독립적으로 갱신할지, 아니면 예약된 각 시각마다 하나의 레플리카만 갱신할지를 제어합니다. 이 설정은 뷰를 생성한 후에는 변경할 수 없습니다. 기본값:false.
갱신 매개변수 변경
ALTER TABLE ... MODIFY REFRESH를 사용해 변경합니다:
EVERY 또는 AFTER)은 필수입니다. 이 구문은 항상 모든 갱신 매개변수(스케줄, RANDOMIZE FOR, DEPENDS ON, 갱신 설정)를 지정된 값으로 모두 대체합니다. 생략된 항목은 기본값으로 재설정되거나(설정), 제거됩니다(의존성, 무작위화).
-
갱신 설정만 변경하려는 경우(예:
refresh_retries)에는 기존 스케줄을 다시 지정하십시오: -
materialized view에서는
ALTER TABLE ... MODIFY SETTING refresh_retries = ...가 지원되지 않습니다. 반드시MODIFY REFRESH를 사용해야 합니다. -
APPEND를 추가하거나 제거하는 것은 지원되지 않습니다. -
all_replicas설정은 생성 후 변경할 수 없습니다.
기타 작업
system.view_refreshes 테이블에서 확인할 수 있습니다. 특히 갱신 진행 상황(실행 중인 경우), 마지막 및 다음 갱신 시각, 갱신이 실패한 경우의 예외 메시지가 포함됩니다.
갱신을 수동으로 중지, 시작, 실행 또는 취소하려면 SYSTEM STOP|START|REFRESH|WAIT|CANCEL VIEW를 사용하십시오.
갱신이 완료될 때까지 기다리려면 SYSTEM WAIT VIEW를 사용하십시오. 특히 뷰를 생성한 후 초기 갱신이 완료될 때까지 기다릴 때 유용합니다.
재미있는 사실: 갱신 쿼리는 현재 갱신 중인 뷰를 읽을 수 있으며, 갱신 전 버전의 데이터를 보게 됩니다. 즉, Conway의 생명 게임을 구현할 수 있습니다: https://pastila.nl/?00021a4b/d6156ff819c83d490ad2dcec05676865#O0LGWTO7maUQIA4AcGUtlA==
윈도우 뷰
이 기능은 실험 단계이며, 향후 릴리스에서 하위 호환성이 깨지는 방식으로 변경될 수 있습니다. allow_experimental_window_view 설정으로 윈도우 뷰와
WATCH 쿼리 사용을 활성화하십시오. set allow_experimental_window_view = 1 명령을 입력하십시오.WATCH 쿼리를 사용해 알림을 전송할 수 있습니다.
윈도우 뷰 생성은 MATERIALIZED VIEW 생성과 유사합니다. 윈도우 뷰는 중간 데이터를 저장하기 위한 내부 스토리지 엔진이 필요합니다. 내부 스토리지는 INNER ENGINE 절을 사용해 지정할 수 있으며, 지정하지 않으면 기본 내부 엔진으로 AggregatingMergeTree를 사용합니다.
TO [db].[table] 없이 윈도우 뷰를 생성할 때는 데이터를 저장할 테이블 엔진인 ENGINE을 반드시 지정해야 합니다.
시간 윈도우 함수
시간 속성
time_attr를 테이블 컬럼으로 설정하거나 now() 함수를 사용해 정의할 수 있습니다. 다음 쿼리는 처리 시간을 사용하는 윈도우 뷰를 생성합니다.
WATERMARK 구문을 사용해 이벤트 시간 처리를 지원합니다.
윈도우 뷰는 세 가지 워터마크 전략을 제공합니다.
STRICTLY_ASCENDING: 지금까지 관측된 최대 타임스탬프의 워터마크를 내보냅니다. 타임스탬프가 최대 타임스탬프보다 작은 행은 지연된 행으로 간주되지 않습니다.ASCENDING: 지금까지 관측된 최대 타임스탬프에서 1을 뺀 워터마크를 내보냅니다. 타임스탬프가 최대 타임스탬프와 같거나 더 작은 행은 지연된 행으로 간주되지 않습니다.BOUNDED: WATERMARK=INTERVAL. 관측된 최대 타임스탬프에서 지정된 지연 시간을 뺀 워터마크를 내보냅니다.
WATERMARK를 사용하여 윈도우 뷰를 생성하는 예시입니다.
ALLOWED_LATENESS=INTERVAL을 설정해 지연 이벤트 처리를 지원합니다. 지연 처리의 예시는 다음과 같습니다.
ALTER TABLE ... MODIFY QUERY statement를 사용하면 윈도우 뷰에 지정된 SELECT 쿼리를 수정할 수 있습니다. 새 SELECT 쿼리의 결과 데이터 구조는 TO [db.]name 절의 유무와 관계없이 원래 SELECT 쿼리와 동일해야 합니다. 중간 상태는 재사용할 수 없으므로 현재 윈도우의 데이터는 손실된다는 점에 유의하십시오.
새 윈도우 모니터링
TO 구문을 사용해 결과를 테이블로 출력할 수도 있습니다.
LIMIT를 지정할 수 있습니다. EVENTS 절을 사용하면 WATCH 쿼리의 축약형을 사용할 수 있으며, 쿼리 결과 대신 최신 쿼리 워터마크만 받습니다.
설정
window_view_clean_interval: 오래된 데이터를 정리하기 위한 윈도우 뷰 정리 간격(초)입니다. 시스템 시간 또는WATERMARK구성에 따라 아직 완전히 트리거되지 않은 윈도우는 유지되며, 그 외 데이터는 삭제됩니다.window_view_heartbeat_interval: watch 쿼리가 살아 있음을 나타내는 하트비트 간격(초)입니다.wait_for_window_view_fire_signal_timeout: 이벤트 시간 처리에서 윈도우 뷰 실행 신호를 기다리는 시간 제한입니다.
예시
data라는 로그 테이블에서 10초마다 클릭 로그의 개수를 집계해야 한다고 가정하겠습니다. 테이블 구조는 다음과 같습니다:
WATCH 쿼리를 사용해 결과를 확인합니다.
data 테이블에 삽입되면,
WATCH 쿼리는 다음과 같이 결과가 출력되어야 합니다:
TO 구문을 사용해 출력을 다른 테이블로 보낼 수도 있습니다.
*window_view*라는 이름을 사용합니다).
윈도우 뷰 사용
- 모니터링: 메트릭 로그를 시간별로 집계하고 계산한 뒤, 결과를 대상 테이블(target table)에 출력합니다. 대시보드는 대상 테이블을 소스 테이블로 사용할 수 있습니다.
- 분석: 시간 윈도우에서 데이터를 자동으로 집계하고 전처리합니다. 이는 대량의 로그를 분석할 때 유용합니다. 전처리를 통해 여러 쿼리에서 반복 계산을 없애고 쿼리 지연 시간을 줄일 수 있습니다.
임시 뷰
- 세션 수명 임시 뷰는 현재 세션이 유지되는 동안에만 존재합니다. 세션이 종료되면 자동으로 삭제됩니다.
- 데이터베이스 없음 임시 뷰에는 데이터베이스 이름을 붙여 지정할 수 없습니다. 임시 뷰는 데이터베이스 바깥(세션 네임스페이스)에 존재합니다.
-
복제되지 않음 / ON CLUSTER 없음
임시 객체는 세션에 로컬로만 존재하므로
ON CLUSTER를 사용해 생성할 수 없습니다. - 이름 해석 임시 객체(테이블 또는 뷰)와 영구 객체의 이름이 같고, 쿼리에서 데이터베이스를 지정하지 않고 해당 이름을 참조하면 임시 객체가 사용됩니다.
-
논리 객체(저장소 없음)
임시 뷰는
SELECT텍스트만 저장합니다(내부적으로View저장소를 사용). 데이터를 영구 저장하지 않으며INSERT를 받을 수 없습니다. -
Engine 절
ENGINE은 지정하지 않아도 됩니다.ENGINE = View로 지정하더라도 무시되며 동일한 논리 뷰로 처리됩니다. -
보안 / 권한
임시 뷰를 생성하려면
CREATE TEMPORARY VIEW권한이 필요하며, 이 권한은CREATE VIEW에 암묵적으로 포함됩니다. -
SHOW CREATE
임시 뷰의 DDL을 출력하려면
SHOW CREATE TEMPORARY VIEW view_name;를 사용하십시오.
구문
OR REPLACE는 임시 뷰에서는 지원되지 않습니다(임시 테이블과 일관성을 맞추기 위함입니다). 임시 뷰를 “대체”해야 하는 경우, 해당 뷰를 삭제한 후 다시 생성하십시오.
예시
지원되지 않는 항목 / 제한 사항
CREATE OR REPLACE TEMPORARY VIEW ...→ 허용되지 않음 (DROP+CREATE사용).CREATE TEMPORARY MATERIALIZED VIEW .../WINDOW VIEW→ 허용되지 않음.CREATE TEMPORARY VIEW db.view AS ...→ 허용되지 않음 (데이터베이스 지정자 사용 불가).CREATE TEMPORARY VIEW view ON CLUSTER 'name' AS ...→ 허용되지 않음 (임시 객체는 세션 로컬임).POPULATE,REFRESH,TO [db.table], 내부 엔진, 그리고 모든 MV 전용 절 → 임시 뷰에는 적용되지 않음.
분산 쿼리 관련 참고 사항
Memory)을 참조하는 경우, 해당 데이터는 임시 테이블과 마찬가지로 분산 쿼리 실행 중 원격 서버로 전송될 수 있습니다.