IdSet으로 필터링하기
IdSet으로 필터링하기 (Filtering with IdSet)
값 목록에서 ID를 조회하는 빠른 쿼리를 만드는 방법을 배우는 페이지예요.
본문
{% hint style="info" %} IdSet 필터링은 단일 스테이지 쿼리 엔진(v1)에서만 지원됩니다. {% endhint %}
일반적인 사용 사례는 id 필드를 값 목록으로 필터링하는 것입니다. 이는 IN 절로 할 수 있지만, IN은 큰 ID 목록에서는 성능이 좋지 않습니다. 큰 ID 목록에는 IdSet 사용을 권장합니다.
함수
ID_SET
ID_SET(columnName, 'sizeThresholdInBytes=8388608;expectedInsertions=5000000;fpp=0.03' )
이 함수는 한 컬럼 값의 base 64 인코딩된 IdSet을 반환합니다. 사용되는 IdSet 구현은 컬럼 데이터 타입에 따라 달라집니다:
- INT - sizeThresholdInBytes를 초과하지 않으면 RoaringBitmap, 초과하면 Bloom Filter.
- LONG - sizeThresholdInBytes를 초과하지 않으면 Roaring64NavigableMap, 초과하면 Bloom Filter.
- 기타 타입 - Bloom Filter
Bloom Filter를 구성하는 데 다음 파라미터가 사용됩니다:
- expectedInsertions - BloomFilter에 기대되는 삽입 수. 양수여야 합니다.
- fpp - BloomFilter에 사용할 false positive 확률. 양수이고 1.0보다 작아야 합니다.
Bloom Filter를 사용하면 필터 결과가 근사값이라는 점에 유의하세요 - (집합 소속에 대한) false-positive 결과가 나올 수 있어 예기치 않은 결과가 발생할 수 있습니다.
IN_ID_SET
IN_ID_SET(columnName, base64EncodedIdSet)
이 함수는 컬럼이 IdSet에 지정된 값 중 하나를 포함하면 1을, 그렇지 않으면 0을 반환합니다.
IN_SUBQUERY
IN_SUBQUERY(columnName, subQuery)
이 함수는 서브쿼리에서 IdSet을 생성한 뒤 Pinot 브로커에서 그 IdSet을 기준으로 id를 필터링합니다.
IN__PARTITIONED__SUBQUERY
IN_PARTITIONED_SUBQUERY(columnName, subQuery)
이 함수는 서브쿼리에서 IdSet을 생성한 뒤 Pinot 서버에서 그 IdSet을 기준으로 id를 필터링합니다.
이 함수는 데이터가 id 컬럼으로 파티셔닝되고 각 서버가 특정 파티션의 전체 데이터를 가질 때 가장 잘 동작합니다. 서브쿼리로 생성된 IdSet은 서버가 제공하는 파티션의 id만 포함하게 되어 더 작아집니다. 따라서 성능이 더 좋아집니다.
{% hint style="info" %}
IN_SUBQUERY에 전달된 쿼리는 어떤 테이블이든 실행될 수 있습니다 — 부모 쿼리에 사용된 테이블로 제한되지 않습니다.
IN_PARTITIONED_SUBQUERY에 전달된 쿼리는 반드시 부모 쿼리와 같은 테이블에서 실행되어야 합니다.
{% endhint %}
예제
IdSet 생성
yearID 컬럼 값의 IdSet을 만들려면 다음을 실행하세요:
SELECT ID_SET(yearID)
FROM baseballStats
WHERE teamID = 'WS1'
| idset(yearID) |
|---|
| ATowAAABAAAAAAA7ABAAAABtB24HbwdwB3EHcgdzB3QHdQd2B3cHeAd5B3oHewd8B30Hfgd/B4AHgQeCB4MHhAeFB4YHhweIB4kHigeLB4wHjQeOB48HkAeRB5IHkweUB5UHlgeXB5gHmQeaB5sHnAedB54HnwegB6EHogejB6QHpQemB6cHqAc= |
INT/LONG가 아닌 컬럼의 IdSet을 만들 때는 expectedInsertions를 구성할 수 있습니다:
SELECT ID_SET(playerName, 'expectedInsertions=10')
FROM baseballStats
WHERE teamID = 'WS1'
| idset(playerName) |
|---|
| AwIBBQAAAAL///////////////////// |
SELECT ID_SET(playerName, 'expectedInsertions=100')
FROM baseballStats
WHERE teamID = 'WS1'
| idset(playerName) |
|---|
| AwIBBQAAAAz///////////////////////////////////////////////9///////f///9/////7///////////////+/////////////////////////////////////////////8= |
fpp 파라미터도 구성할 수 있습니다:
SELECT ID_SET(playerName, 'expectedInsertions=100;fpp=0.01')
FROM baseballStats
WHERE teamID = 'WS1'
| idset(playerName) |
|---|
| AwIBBwAAAA/////////////////////////////////////////////////////////////////////////////////////////////////////////9///////////////////////////////////////////////7//////8= |
IdSet의 값으로 필터링
IN_ID_SET 함수를 사용해 IdSet을 기준으로 쿼리를 필터링할 수 있습니다. IdSet 안의 *yearID*에 대한 행을 반환하려면 다음을 실행하세요:
SELECT yearID, count(*)
FROM baseballStats
WHERE IN_ID_SET(
yearID,
'ATowAAABAAAAAAA7ABAAAABtB24HbwdwB3EHcgdzB3QHdQd2B3cHeAd5B3oHewd8B30Hfgd/B4AHgQeCB4MHhAeFB4YHhweIB4kHigeLB4wHjQeOB48HkAeRB5IHkweUB5UHlgeXB5gHmQeaB5sHnAedB54HnwegB6EHogejB6QHpQemB6cHqAc='
) = 1
GROUP BY yearID
IdSet에 없는 값으로 필터링
IdSet에 없는 *yearID*에 대한 행을 반환하려면 다음을 실행하세요:
SELECT yearID, count(*)
FROM baseballStats
WHERE IN_ID_SET(
yearID,
'ATowAAABAAAAAAA7ABAAAABtB24HbwdwB3EHcgdzB3QHdQd2B3cHeAd5B3oHewd8B30Hfgd/B4AHgQeCB4MHhAeFB4YHhweIB4kHigeLB4wHjQeOB48HkAeRB5IHkweUB5UHlgeXB5gHmQeaB5sHnAedB54HnwegB6EHogejB6QHpQemB6cHqAc='
) = 0
GROUP BY yearID
브로커에서 필터링
Pinot 브로커에서 IdSet 안의 *yearID*에 대한 행을 필터링하려면 다음 쿼리를 실행하세요:
SELECT yearID, count(*)
FROM baseballStats
WHERE IN_SUBQUERY(
yearID,
'SELECT ID_SET(yearID) FROM baseballStats WHERE teamID = ''WS1'''
) = 1
GROUP BY yearID
IdSet에 없는 *yearID*에 대한 행을 Pinot 브로커에서 필터링하려면 다음 쿼리를 실행하세요:
SELECT yearID, count(*)
FROM baseballStats
WHERE IN_SUBQUERY(
yearID,
'SELECT ID_SET(yearID) FROM baseballStats WHERE teamID = ''WS1'''
) = 0
GROUP BY yearID
서버에서 필터링
Pinot 서버에서 IdSet 안의 *yearID*에 대한 행을 필터링하려면 다음 쿼리를 실행하세요:
SELECT yearID, count(*)
FROM baseballStats
WHERE IN_PARTITIONED_SUBQUERY(
yearID,
'SELECT ID_SET(yearID) FROM baseballStats WHERE teamID = ''WS1'''
) = 1
GROUP BY yearID
IdSet에 없는 *yearID*에 대한 행을 Pinot 서버에서 필터링하려면 다음 쿼리를 실행하세요:
SELECT yearID, count(*)
FROM baseballStats
WHERE IN_PARTITIONED_SUBQUERY(
yearID,
'SELECT ID_SET(yearID) FROM baseballStats WHERE teamID = ''WS1'''
) = 0
GROUP BY yearID