DELETE 문은 표현식 expr과 일치하는 [db.]table 테이블의 행을 제거합니다. 이 기능은 *MergeTree 테이블 엔진 계열에서만 사용할 수 있습니다.
DELETE”라고 합니다.
예시
경량 DELETE는 데이터를 즉시 삭제하지 않습니다
DELETE는 뮤테이션(mutation)으로 구현되며, 행을 삭제된 것으로 표시하지만 즉시 물리적으로 삭제하지는 않습니다.
기본적으로 DELETE SQL 문은 행이 삭제된 것으로 표시되는 작업이 완료될 때까지 기다린 후 반환됩니다. 데이터 양이 많으면 이 작업에 오랜 시간이 걸릴 수 있습니다. 또는 설정 lightweight_deletes_sync를 사용해 백그라운드에서 비동기적으로 실행할 수 있습니다. 이 설정을 비활성화하면 DELETE SQL 문은 즉시 반환되지만, 백그라운드 뮤테이션이 완료될 때까지 데이터가 쿼리에서 계속 보일 수 있습니다.
뮤테이션은 삭제된 것으로 표시된 행을 물리적으로 삭제하지 않으며, 이는 다음 머지 때만 수행됩니다. 따라서 일정 기간 동안 데이터가 실제로는 스토리지에서 삭제되지 않고 삭제된 것으로만 표시될 수 있습니다.
예측 가능한 시간 내에 데이터가 스토리지에서 삭제되도록 보장해야 한다면 테이블 설정 min_age_to_force_merge_seconds 사용을 고려하십시오. 또는 ALTER TABLE … DELETE 명령을 사용할 수 있습니다. ALTER TABLE ... DELETE를 사용해 데이터를 삭제하면 영향을 받는 모든 파트를 다시 생성하므로 상당한 리소스를 사용할 수 있다는 점에 유의하십시오.
대량의 데이터 삭제
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 privilege가 필요합니다. 특정 사용자가 특정 table에서 DELETE SQL 문을 실행할 수 있도록 하려면 다음 명령을 실행하십시오.
ClickHouse 내부에서 경량 DELETE가 작동하는 방식
-
영향을 받은 행에 “마스크”가 적용됩니다
DELETE FROM table ...쿼리가 실행되면 ClickHouse는 각 행이 “existing”인지 “deleted”인지 표시하는 마스크를 저장합니다. “deleted”로 표시된 행은 이후 쿼리 결과에서 제외됩니다. 하지만 행이 실제로 제거되는 것은 이후 머지 과정에서입니다. 이 마스크를 기록하는 작업은ALTER TABLE ... DELETE쿼리에서 수행되는 작업보다 훨씬 더 경량합니다. 이 마스크는 보이는 모든 행에True를, 삭제된 행에False를 저장하는 숨겨진_row_exists시스템 컬럼으로 구현됩니다. 이 컬럼은 파트 내 일부 행이 삭제된 경우에만 해당 파트에 존재합니다. 파트의 모든 값이True이면 이 컬럼은 존재하지 않습니다. -
SELECT쿼리는 마스크를 포함하도록 변환됩니다 마스킹된 컬럼이 쿼리에서 사용되면SELECT ... FROM table WHERE condition쿼리는 내부적으로_row_exists에 대한 프레디케이트가 추가되어 다음과 같이 변환됩니다:실행 시에는 반환하면 안 되는 행을 판별하기 위해_row_exists컬럼을 읽습니다. 삭제된 행이 많으면 ClickHouse는 나머지 컬럼을 읽을 때 어떤 그래뉼을 완전히 건너뛸 수 있는지 판단할 수 있습니다. -
DELETE쿼리는ALTER TABLE ... UPDATE쿼리로 변환됩니다DELETE FROM table WHERE condition은ALTER TABLE table UPDATE _row_exists = 0 WHERE condition뮤테이션으로 변환됩니다. 내부적으로 이 뮤테이션은 두 단계로 실행됩니다:-
각 개별 파트에 대해
SELECT count() FROM table WHERE condition명령을 실행하여 해당 파트가 영향을 받았는지 확인합니다. -
위 명령 결과를 바탕으로 영향을 받은 파트에는 뮤테이션이 적용되고, 영향을 받지 않은 파트에는 하드링크가 생성됩니다. wide 파트의 경우 각 행의
_row_exists컬럼이 업데이트되고, 다른 모든 컬럼 파일은 하드링크됩니다. compact 파트의 경우 모든 컬럼이 하나의 파일에 함께 저장되므로 모든 컬럼이 다시 기록됩니다.
DELETE는 영향을 받은 파트의 모든 컬럼 파일을 다시 기록하지 않으므로 기존ALTER TABLE ... DELETE보다 성능이 더 좋습니다. -
각 개별 파트에 대해