Sangwon
09/04/2026, 7:31 AMRocky
09/04/2026, 7:31 AMEXPLAIN 결과에서 *`IcebergEqualityDeleteScanNode`*가 나타나는 이유는 쿼리하려는 Apache Iceberg 테이블(주로 v2)에 Equality Delete 파일이 포함되어 있기 때문입니다.
이 노드는 삭제된 데이터를 걸러내기 위해 *실시간으로 Join(주로 Anti Hash Join)*을 수행하는데, 이 과정에서 CPU와 메모리 소모가 매우 커 성능 저하의 주된 원인이 됩니다. 이를 회피하거나 해결하는 방법은 크게 3가지가 있습니다.
1. Iceberg 테이블 데이터 최적화 (Compaction)
가장 근본적인 해결책입니다. Iceberg의 Equality Delete는 "나중에 읽을 때 처리(Merge-on-Read)"하는 방식이므로, 삭제 파일이 쌓일수록 느려집니다.
* 해결 방법: Spark나 Flink를 사용하여 rewriteDataFiles 또는 rewriteDeleteFiles 작업을 수행하세요.
* 효과: 흩어져 있는 삭제 파일들을 실제 데이터 파일에 병합하거나, 성능이 더 좋은 Position Delete 방식으로 변환하여 `IcebergEqualityDeleteScanNode`의 부하를 없애거나 줄여줍니다.
2. StarRocks Materialized View (MV) 활용
Iceberg 테이블의 데이터를 StarRocks 내부 스토리지로 가속하는 방법입니다.
* 해결 방법: 해당 Iceberg 테이블을 기반으로 *Asynchronous Materialized View*를 생성하세요.
* 효과: MV를 생성하면 StarRocks가 데이터를 자신의 최적화된 포맷(기본적으로 중복 제거가 완료된 상태)으로 로컬에 저장합니다. 이후 쿼리는 Iceberg의 삭제 파일을 매번 계산할 필요 없이 로컬 MV에서 즉시 결과를 가져오므로 매우 빠릅니다.
3. 데이터 입력 단계 조정 (Flink/Spark Sink 설정)
만약 Flink나 Spark를 통해 Iceberg에 데이터를 넣고 있다면, 삭제 방식 설정을 변경해 볼 수 있습니다.
* 해결 방법: 가능하면 *Position Delete*를 우선 사용하도록 설정하거나, Upsert 시 발생하는 Equality Delete의 발생 빈도를 줄이도록 배치 크기를 조절합니다. (다만, 실시간 CDC 상황에서는 Equality Delete가 불가피한 경우가 많습니다.)
요약
* *즉각적인 성능 개선*이 필요하다면: StarRocks에서 *Materialized View*를 만드세요.
* 원천 데이터(Iceberg) 자체를 가볍게 만들고 싶다면: Iceberg *Compaction(데이터 재작성)*을 수행하세요.
`IcebergEqualityDeleteScanNode`는 데이터를 정확하게 조회하기 위한 필수 단계이므로, 단순히 설정으로 끄는 방법은 없으며(끄면 삭제된 데이터가 다시 나타남), 위와 같이 *"읽기 시점의 연산량을 미리 줄여두는 방식"*으로 회피해야 합니다.
References
• data_source/catalog/iceberg/iceberg_catalog.md
• table_design/table_types/primary_key_table.md
• data_source/feature-support-data-lake-analytics.md
• data_source/catalog/iceberg/DML.mdSangwon
09/04/2026, 7:32 AMRocky
09/04/2026, 7:32 AMCREATE MATERIALIZED VIEW mv1 REFRESH ASYNC START('...') EVERY(...) AS SELECT * FROM iceberg_table;
* 장점: MV를 생성하면 StarRocks가 Iceberg의 Equality Delete를 한 번 계산해서 결과를 자기 저장소에 최적화된 형태로 저장합니다. 쿼리 시 IcebergEqualityDeleteScanNode 자체가 사라지고, 매우 빠른 로컬 스캔으로 대체됩니다.
* 주의: 데이터의 실시간성은 MV의 Refresh 주기(예: 10분, 1시간 등)에 따라 결정됩니다.
2. 데이터 캐시(Data Cache) 활성화
원본 테이블을 바꿀 수 없다면, 적어도 삭제 파일과 데이터 파일을 읽어오는 I/O 속도라도 높여야 합니다.
* 방법: 쿼리 실행 전 세션 변수를 설정합니다.
sql
SET enable_scan_datacache = true;
* 효과: 첫 조회 이후에는 원격 저장소(S3/HDFS)가 아닌 BE의 로컬 디스크(SSD 등)에서 삭제 파일과 데이터 파일을 읽어옵니다. `IcebergEqualityDeleteScanNode`가 수행하는 Hash Join 연산에 필요한 데이터를 훨씬 빠르게 로딩할 수 있습니다.
3. 쿼리 조건 최적화 (Partition/Column Pruning)
`IcebergEqualityDeleteScanNode`가 느린 이유는 읽어야 할 데이터와 매칭되는 '삭제 파일'이 많기 때문입니다.
* 방법: WHERE 절에 파티션 컬럼이나 필터 조건(Predicate)을 최대한 구체적으로 추가하세요.
* 효과: 읽어야 할 데이터 파일의 개수가 줄어들면, 그에 딸린 삭제 파일의 개수도 줄어들어 Node 내부의 Join 연산량이 급격히 감소합니다.
4. StarRocks 버전 확인 (v3.4 이상 권장)
StarRocks 최신 버전(3.4+)에는 Iceberg V2 삭제 파일을 읽는 과정에서 메모리 사용량을 줄이고 중복 읽기를 최적화하는 기능이 포함되어 있습니다. 만약 하위 버전을 사용 중이라면 엔진 업그레이드만으로도 성능 개선을 기대할 수 있습니다.
5. 쿼리 자원 할당량 증대 (임시 방편)
노드의 연산을 피할 수 없다면, 연산 속도를 높이기 위해 더 많은 자원을 할당합니다.
* 방법:
sql
SET query_mem_limit = 16 _ 1024 _ 1024 * 1024; -- 메모리 제한 상향
SET parallel_fragment_exec_instance_num = 16; -- 병렬 처리 수 상향
요약하자면:
테이블 수정을 못 하시는 상황이므로, *Materialized View*를 만들어 StarRocks가 대신 삭제 연산을 미리 처리하게 하거나, *Data Cache*를 켜서 I/O 속도를 높이는 것이 최선입니다.
References
• data_source/catalog/iceberg/iceberg_catalog.md
• release_notes/release-3.4.md
• using_starrocks/caching/query_cache.md
• sql-reference/System_variable.md
References
• data_source/datalake_faq.md
• data_source/catalog/iceberg/iceberg_catalog.md
• using_starrocks/caching/query_cache.md
• release_notes/release-3.4.md