메인 콘텐츠로 건너뛰기
경량 DELETE 문은 표현식 expr에 일치하는 [db.]table 테이블의 행을 삭제합니다. 이 기능은 *MergeTree 테이블 엔진 계열에서만 사용할 수 있습니다.
DELETE FROM [db.]table [ON CLUSTER cluster] [IN PARTITION partition_expr] WHERE expr;
이는 비용이 큰 작업인 ALTER TABLE … DELETE 명령과 구분하기 위해 “경량 DELETE”라고 부릅니다.

예시

-- `hits` 테이블에서 `Title` 컬럼에 `hello` 텍스트가 포함된 모든 행을 삭제합니다
DELETE FROM hits WHERE Title LIKE '%hello%';

경량 DELETE는 데이터를 즉시 삭제하지 않습니다

경량 DELETE는 행을 삭제된 것으로 표시하지만 즉시 물리적으로 삭제하지 않는 뮤테이션으로 구현됩니다. 기본적으로 DELETE SQL 문은 행을 삭제된 것으로 표시하는 작업이 완료될 때까지 기다린 후 반환됩니다. 데이터 양이 많으면 이 작업에 오랜 시간이 걸릴 수 있습니다. 또는 lightweight_deletes_sync 설정을 사용해 백그라운드에서 비동기적으로 실행할 수 있습니다. 이 옵션을 비활성화하면 DELETE SQL 문은 즉시 반환되지만, 백그라운드 뮤테이션이 완료될 때까지 데이터가 여전히 쿼리에서 보일 수 있습니다. 이 뮤테이션은 삭제된 것으로 표시된 행을 물리적으로 삭제하지 않으며, 이는 다음 머지 시에만 수행됩니다. 따라서 일정 기간 동안 데이터가 실제로는 스토리지에서 삭제되지 않고 삭제된 것으로만 표시될 수 있습니다. 예측 가능한 시간 안에 데이터가 스토리지에서 삭제되도록 보장해야 한다면 테이블 설정 min_age_to_force_merge_seconds 사용을 고려하십시오. 또는 ALTER TABLE … DELETE 명령을 사용할 수 있습니다. ALTER TABLE ... DELETE를 사용해 데이터를 삭제하면 영향을 받는 모든 파트를 다시 생성하므로 상당한 리소스를 사용할 수 있다는 점에 유의하십시오.

대량의 데이터 삭제

대량 삭제는 ClickHouse 성능에 부정적인 영향을 줄 수 있습니다. 테이블의 모든 행을 삭제하려는 경우 TRUNCATE TABLE 명령 사용을 고려해 보십시오. 삭제가 자주 필요할 것으로 예상된다면 사용자 지정 파티셔닝 키를 사용하는 것이 좋습니다. 그러면 ALTER TABLE ... DROP PARTITION 명령을 사용해 해당 파티션에 속한 모든 행을 빠르게 삭제할 수 있습니다.

경량 DELETE의 제한 사항

프로젝션이 있는 테이블에서의 경량 DELETE

기본적으로 프로젝션이 있는 테이블에서는 DELETE가 작동하지 않습니다. 이는 프로젝션의 행이 DELETE 작업의 영향을 받을 수 있기 때문입니다. 하지만 이 동작을 변경하는 MergeTree 설정 lightweight_mutation_projection_mode가 있습니다.

경량 DELETE 사용 시 성능 고려 사항

경량 DELETE 문으로 대량의 데이터를 삭제하면 SELECT 쿼리 성능에 악영향을 줄 수 있습니다. 다음과 같은 요인도 경량 DELETE 성능에 부정적인 영향을 줄 수 있습니다:
  • DELETE 쿼리의 WHERE 조건이 복잡한 경우.
  • 뮤테이션 큐에 다른 뮤테이션이 많이 쌓여 있으면, 테이블의 모든 뮤테이션이 순차적으로 실행되므로 성능 문제가 발생할 수 있습니다.
  • 영향을 받는 테이블에 데이터 파트가 매우 많은 경우.
  • 컴팩트 파트(Compact 파트)에 데이터가 많은 경우. Compact 파트에서는 모든 컬럼이 하나의 파일에 저장됩니다.

DELETE 권한

DELETE를 사용하려면 ALTER DELETE 권한이 필요합니다. 특정 사용자가 특정 테이블에서 DELETE SQL 문을 실행할 수 있도록 하려면 다음 명령을 실행하십시오:
GRANT ALTER DELETE ON db.table to username;

ClickHouse에서 경량 DELETE가 내부적으로 작동하는 방식

  1. 영향을 받는 행에 “마스크”가 적용됩니다 DELETE FROM table ... 쿼리가 실행되면 ClickHouse는 각 행을 “존재” 또는 “삭제됨”으로 표시하는 마스크를 저장합니다. 이렇게 표시된 “삭제된” 행은 이후 쿼리 결과에서 제외됩니다. 하지만 행 자체가 실제로 제거되는 것은 이후 머지 과정에서입니다. 이 마스크를 기록하는 작업은 ALTER TABLE ... DELETE 쿼리에서 수행하는 작업보다 훨씬 가볍습니다. 이 마스크는 표시 가능한 모든 행에 True를, 삭제된 행에 False를 저장하는 숨겨진 _row_exists 시스템 컬럼으로 구현됩니다. 이 컬럼은 해당 파트에서 일부 행이 삭제된 경우에만 존재합니다. 파트의 모든 값이 True이면 이 컬럼은 존재하지 않습니다.
  2. SELECT 쿼리는 마스크를 포함하도록 변환됩니다 마스크가 적용된 컬럼이 쿼리에서 사용되면 SELECT ... FROM table WHERE condition 쿼리는 내부적으로 _row_exists에 대한 프레디케이트가 추가되어 다음과 같이 변환됩니다:
    SELECT ... FROM table PREWHERE _row_exists WHERE condition
    
    실행 시에는 _row_exists 컬럼을 읽어 반환하면 안 되는 행을 판별합니다. 삭제된 행이 많으면 ClickHouse는 나머지 컬럼을 읽을 때 어떤 그래뉼을 완전히 건너뛸 수 있는지도 판단할 수 있습니다.
  3. DELETE 쿼리는 ALTER TABLE ... UPDATE 쿼리로 변환됩니다 DELETE FROM table WHERE conditionALTER TABLE table UPDATE _row_exists = 0 WHERE condition 뮤테이션으로 변환됩니다. 내부적으로 이 뮤테이션은 두 단계로 실행됩니다:
    1. 각 개별 파트에 대해 SELECT count() FROM table WHERE condition 명령을 실행하여 해당 파트가 영향을 받는지 확인합니다.
    2. 위 명령의 결과를 바탕으로 영향을 받는 파트에는 뮤테이션이 적용되고, 영향을 받지 않는 파트에는 하드링크가 생성됩니다. wide 파트의 경우 각 행의 _row_exists 컬럼이 업데이트되고, 나머지 모든 컬럼 파일은 하드링크됩니다. 컴팩트 파트의 경우 모든 컬럼이 하나의 파일에 함께 저장되므로 모든 컬럼을 다시 기록합니다.
    위 단계에서 알 수 있듯이, 마스킹 기법을 사용하는 경량 DELETE는 영향을 받는 파트의 모든 컬럼 파일을 다시 기록하지 않으므로 기존 ALTER TABLE ... DELETE보다 성능이 더 좋습니다.
마지막 수정일 2026년 6월 10일