Join Order Benchmark

Join Order Benchmark (JOB)

실제 세계의 고상관 데이터(IMDb 스냅샷)에 대해 113개의 분석 쿼리로 쿼리 옵티마이저를 시험하는 벤치마크입니다. 카디널리티 추정과 조인 순서 최적화 성능을 평가하는 데 업계 표준으로 자리 잡았으며, 21개 테이블에 약 7400만 행을 담고 있습니다.

출처: 문서

본문

Join Order Benchmark (JOB)는 실제 세계의 고도로 상관된 데이터셋(IMDb 스냅샷)에 대해 113개의 분석 쿼리로 쿼리 옵티마이저를 시험합니다. 도입 이후 JOB 벤치마크는 카디널리티 추정과 조인 순서 최적화를 포함한 관계형 데이터베이스 쿼리 옵티마이저의 성능을 평가하는 사실상의 표준이 되었습니다. 균일하고 독립적인 데이터를 가정하는 합성 벤치마크와 달리, JOB는 편향과 상관관계가 있는 실제 데이터를 사용하므로 조인 순서와 카디널리티 추정에 대한 까다로운 시험을 제공합니다.

이 데이터셋은 21개 테이블에 걸쳐 약 7400만 행을 보유하며 ClickHouse에서 압축 시 약 1.15 GiB를 차지합니다.

113개 쿼리는 33개 패밀리(1~33)로 구성됩니다. 패밀리(a, b, c, …) 내의 쿼리들은 동일한 조인 그래프를 공유하지만 선택(selection) 프레디킷에서 차이가 있습니다.

참고문헌

테이블 생성 (Creating the tables)

JOB 데이터셋은 21개 테이블로 구성된 IMDb 스냅샷입니다. 테이블 정의는 ClickHouse 저장소의 init_cloud.sql에 있습니다.

각 테이블은 원래 PostgreSQL 스키마(모든 테이블이 id integer NOT NULL PRIMARY KEY를 선언)를 반영해 기본 키 컬럼 id로 정렬되는 MergeTree 엔진을 사용합니다. Nullable PostgreSQL 컬럼은 Nullable(...) 타입으로 매핑됩니다.

테이블 생성:

curl -O https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/tests/benchmarks/job/init_cloud.sql
clickhouse client --query "CREATE DATABASE IF NOT EXISTS job"
clickhouse client --database job --queries-file init_cloud.sql

데이터 로딩 (Loading the data)

데이터는 JOB이 사용하는 원본 IMDb 스냅샷에서 비롯되며, 테이블당 하나의 CSV 파일(aka_name.csv, title.csv, …)로 배포됩니다. 이 CSV들은 ESCAPE '\'를 사용하는 PostgreSQL COPY 의미론을 따릅니다: 백슬래시는 따옴표로 묶인 필드 내부에서만 따옴표 문자를 이스케이프하고, 따옴표 밖의 백슬래시는 리터럴 문자입니다. ClickHouse는 RFC 4180 CSV(따옴표 이중화, 백슬래시 이스케이프 없음)를 기대하므로 파일을 먼저 다시 인코딩해야 합니다.

convert_csv.py가 그 재인코딩을 수행합니다. stdin에서 원본 CSV를 읽고 stdout으로 표준 CSV를 쓰며, 포함된 따옴표를 이중화하고 빈 따옴표 없는 필드(Nullable 컬럼에서 ClickHouse가 NULL로 매핑)를 보존합니다.

원본 CSV로 테이블을 구성하려면:

  • 테이블을 생성하세요(위 참조).
  • Join Order Benchmark 저장소의 지침에 따라 IMDb 데이터셋을 imdb.tgz 파일로 내려받으세요.
  • 데이터를 변환하고 임포트하세요:
set -euo pipefail

for table in aka_name aka_title cast_info char_name comp_cast_type company_name \
             company_type complete_cast info_type keyword kind_type link_type \
             movie_companies movie_info movie_info_idx movie_keyword movie_link \
             name person_info role_type title; do
    echo "Loading ${table} ..."
    python3 convert_csv.py < "${table}.csv" > "${table}.clean.csv"
    clickhouse client --database job --query "INSERT INTO ${table} FORMAT CSV" < "${table}.clean.csv"
done

테이블이 채워지면 나중에 더 빠른 재임포트를 위해 Parquet로 내보낼 수 있습니다. 예: clickhouse client --database job --query "SELECT * FROM title ORDER BY id FORMAT Parquet" > title.parquet.

상세 테이블 크기:

Table size (in rows) size (compressed in ClickHouse)
aka_name 901,343 31.86 MiB
aka_title 361,472 14.32 MiB
cast_info 36,244,344 296.25 MiB
char_name 3,140,339 107.95 MiB
comp_cast_type 4 132.00 B
company_name 234,997 8.38 MiB
company_type 4 162.00 B
complete_cast 135,086 748.80 KiB
info_type 113 1.25 KiB
keyword 134,170 1.88 MiB
kind_type 7 177.00 B
link_type 18 284.00 B
movie_companies 2,609,129 21.20 MiB
movie_info 14,835,720 300.46 MiB
movie_info_idx 1,380,035 8.01 MiB
movie_keyword 4,523,930 21.06 MiB
movie_link 29,997 178.21 KiB
name 4,167,491 131.16 MiB
person_info 2,963,664 154.12 MiB
role_type 12 246.00 B
title 2,528,312 78.04 MiB
Total 74,190,187 1.15 GiB

(ClickHouse의 압축 크기는 system.tables.total_bytes에서 가져왔으며 위 테이블 정의에 기반합니다.)

쿼리 (Queries)

113개의 JOB 쿼리는 ClickHouse 저장소의 여기에서 찾을 수 있습니다. 실행에 사용한 설정은 settings.json에 있습니다. 특정 쿼리의 알려진 문제와 참고사항은 README를 확인하세요.

쿼리는 테이블을 이름으로 참조하므로 job 데이터베이스에서 실행하세요(예: clickhouse client --database job).

예제 쿼리(1a):

SELECT MIN(mc.note) AS production_note,
       MIN(t.title) AS movie_title,
       MIN(t.production_year) AS movie_year
FROM company_type AS ct,
     info_type AS it,
     movie_companies AS mc,
     movie_info_idx AS mi_idx,
     title AS t
WHERE ct.kind = 'production companies'
  AND it.info = 'top 250 rank'
  AND mc.note NOT LIKE '%(as Metro-Goldwyn-Mayer Pictures)%'
  AND (mc.note LIKE '%(co-production)%'
       OR mc.note LIKE '%(presents)%')
  AND ct.id = mc.company_type_id
  AND t.id = mc.movie_id
  AND t.id = mi_idx.movie_id
  AND mc.movie_id = mi_idx.movie_id
  AND it.id = mi_idx.info_type_id;

성능 벤치마크 (Performance benchmark)

ClickHouse는 릴리스된 모든 버전에 걸쳐 JOB 쿼리 성능을 추적합니다. ClickHouse versions benchmark 페이지에서 113개 모든 JOB 쿼리의 실행 시간을 살펴보고 성능이 시간에 따라 어떻게 진화했는지 확인할 수 있습니다.

더 알아보기 (Learn more)