데이터셋 프로젝션은 다양한 쿼리에 대한 성능을 향상시킬 수 있습니다. 여러 쿼리 패턴(예: 두 개의 별도 열에 대한 필터링)에 최적화할 데이터셋이 있는 경우, 데이터셋에 프로젝션을 추가해야 합니다. 프로젝션의 구체적인 유즈케이스 예시는 아래에 나열되어 있습니다.
각 프로젝션은 일반적으로 하나의 쿼리 패턴을 지원하며, 이는 열 집합에 대한 필터 또는 조인에 초점을 맞춥니다. 프로젝션은 데이터셋에 여러 개 추가할 수 있으며, 모든 열 유형이 프로젝션에서 지원됩니다. 게다가, 프로젝션은 스냅샷 또는 점진적으로 빌드된 데이터셋에도 추가할 수 있습니다. Noho 서비스는 프로젝션을 관리하며, 프로젝션 설정시 데이터셋 스키마에 참조됩니다.
프로젝션에는 몇 가지 제한 사항이 있습니다:
아래의 예시 유즈케이스를 검토하여 프로젝션이 사용 사례에 적합한지 알아보세요. 프로젝션 설정하는 방법을 배우면서 시작하세요.
많은 종류의 쿼리가 프로젝션의 이점을 누릴 수 있습니다. 아래 예시에서는 다음과 같은 내용을 설명합니다:
주어진 열의 순서화된 목록이 있으면 목록의 접두사에 대한 필터를 최적화합니다. 프로젝션은 열을 상수 값과 비교하는 필터만 가속화합니다. 그리고 스트링 열에 대한 필터는 대소문자 구분해야 합니다.
예를 들어, 열 ["x", "y", "z"]
에 대한 필터에 최적화된 프로젝션이 있다고 가정합니다.
다음과 같은 유형의 쿼리를 가속화합니다:
SELECT * FROM dataset WHERE x = 5 AND y = 10 AND z = '15'
SELECT * FROM dataset WHERE x = 5 AND y = 10
SELECT * FROM dataset WHERE x = 5 AND q = 3
q = 3
), Spark는 데이터 소스로 "푸시"할 수 있는 필터 조건을 자동으로 풀고 나서 나머지 조건을 적용합니다.그러나 다음과 같은 유형의 쿼리는 최적화되지 않습니다:
SELECT * FROM dataset WHERE abs(x) == 10
abs(x) == 10
은 열을 상수 값과 비교하지 않습니다.SELECT * FROM dataset WHERE x % 100 == 10
x % 100 == 10
은 열을 상수 값과 비교하지 않습니다.SELECT * FROM dataset WHERE y = 10
["y"]
는 ["x", "y", "z"]
의 접두사가 아닙니다.SELECT * FROM dataset WHERE z = '15'
["z"]
는 ["x", "y", "z"]
의 접두사가 아닙니다.
["z"]
는 ["x", "y", "z"]
의 접두사가 아닙니다.SELECT * FROM dataset WHERE x = 5 OR q = 3
x = 5
필터를 데이터 소스로 "푸시"할 수 없습니다. 왜냐하면 x = 5
가 거짓이지만 q = 3
이 참인 행을 놓칠 수 있기 때문입니다.프로젝션은 필터 열에서 범위 쿼리를 선택적으로 가속화할 수 있습니다. 예를 들어:
SELECT * FROM dataset WHERE x > 5 AND x < 10
SELECT * FROM dataset WHERE s LIKE 'SOME_PREFIX%'
주어진 열의 순서 없는 집합과 버킷 수가 주어진 경우, 해당 집합과 버킷 수에서 조인(만)을 최적화합니다.
예를 들어, {"x", "y"}
에서 조인에 최적화된 프로젝션은 다음 유형의 쿼리를 최적화합니다:
SELECT * FROM dataset1 INNER JOIN dataset2 ON dataset1.x = dataset2.x AND dataset1.y = dataset2.y
그러나 다음 쿼리는 최적화되지 않습니다:
SELECT * FROM dataset1 INNER JOIN dataset2 ON dataset1.x = dataset2.x
Foundry에서 대규모 데이터셋의 조인은 일반적으로 정렬 병합 조인을 수행합니다. 이 과정에서 조인 키에 따라 각 데이터셋을 분할하고, 해당 키로 각 분할을 정렬한 다음 동일한 키를 가진 (정렬된) 분할을 병합합니다.
Foundry의 대부분의 프로젝션 사용자는 정렬 병합 조인을 수행할 때 프로젝션이 이미 정렬되어 있다는 사실을 기본적으로 활용하지 않기 때문에, Spark 쿼리 계획에서 정렬을 볼 수 있습니다. 변환에서는 Spark 프로필 BUCKET_SORTED_SCAN_ENABLED
을 사용하여 프로젝션의 정렬 사실에 따라 Spark의 동작을 수정할 수 있지만, 이것이 항상 성능을 개선하지는 않으며 성능이 나빠질 수도 있습니다.
Foundry에서 집계는 일반적으로 데이터셋(즉, 데이터셋의 분할)에 대한 셔플 교환을 수행하는 것을 포함합니다. 조인에 최적화된 모든 프로젝션의 경우 해시 버킷화되어 있는 프로젝션에서 읽을 때 소비자는 이러한 셔플을 방지할 수 있습니다. 이로 인해 집계 중에 성능이 크게 향상됩니다. 추가로 제공되는 프로젝션(기본 키 열에 대한 프로젝션)이 특히 유용한 경우는 프로젝션에 의해 수행된 압축과 프로젝션의 해시 버킷화를 집계에 활용할 수 있는 점 때문에, 점진적으로 추가 방식으로 업데이트된 데이터셋의 기본 키 기대 검사가 있습니다.
점진적 파이프라인은 매우 높은 파일 수와 그에 따른 읽기 성능 저하를 초래할 수 있습니다. 예를 들어, 5분마다 10개의 파티션을 작성하는 파이프라인은 연간 천만 개 이상의 파일을 작성합니다. 이는 입력 파티션 목록을 작성하는 것과 같은 이유로 읽기가 어렵습니다.
프로젝션은 이러한 점진적 파이프라인을 투명하게 압축할 수 있는 방법을 제공합니다. 필터 또는 조인에 최적화된 프로젝션을 설정하고 읽기를 사용하면 됩니다. 점진적 파이프라인에 대한 프로젝션 사용에 대해 자세히 알아보세요.
프로젝션이 완전히 최신 상태가 아니더라도 사용자는 프로젝션의 필터 또는 조인 최적화를 활용할 수 있습니다. 프로젝션의 마지막 빌드 시점의 최신 트랜잭션과 현재 데이터셋의 최신 트랜잭션 사이에 SNAPSHOT 또는 DELETE 트랜잭션이 없고(또는 기존 파일을 수정하는 UPDATE 트랜잭션이 없는 경우), 기준 데이터셋이 있어야 합니다.
CSV는 데이터 쿼리에 비효율적인 파일 형식이지만, Foundry에 업로드된 데이터(파일 시스템 소스에서의 Data Connection, 수동 업로드 등)가 처음에는 CSV 형식일 수 있습니다. 이러한 CSV를 Parquet과 같은 더 효율적인 형식으로 변환하는 방법 중 하나는 변환 작업을 생성하는 것입니다. 또 다른 방법으로는 프로젝션을 추가할 수 있습니다. 읽기 작업은 최적화된 프로젝션을 사용하여 성능이 향상되지만, 데이터셋은 여전히 원본 CSV 파일을 포함합니다.