Ken
본 글은 유전체 데이터 분석 케이스의 적합성을 확인하기 위해 작성되었고, 비즈니스 유즈케이스 이해와 성능 테스트를 진행한 사항을 포함하고 있습니다. 30억 건의 데이터를 기준으로 성능 등을 확인하였습니다.
- 1. 유전체 분석의 이해
- 1.1 유전체 변이(Variant) 데이터란?
- 1.2 유전체 분석 파이프라인
- 1.3 주요 쿼리 패턴
- 2. 데이터 모델 설계
- 2.1 스키마 구조 (106개 컬럼)
- 2.2 데이터 타입 선택 전략
- 3. 인덱싱 전략
- 3.1 Primary Index (ORDER BY)
- 3.2 Bloom Filter Index (gene)
- 3.3 N-gram Bloom Filter (유전자명 부분 검색)
- 3.4 파티셔닝
- 4. 벤치마크 결과 (30억건)
- 4.1 테스트 환경
- 4.2 스토리지 효율
- 4.3 쿼리 성능 벤치마크
- Q1. Region-based Point Query
- Q2. Gene Filter with Impact
- Q3. Partial Gene Name Search
- Q4. Gene-level Aggregation
- Q5. Complex Multi-condition Filter
- Q6. Sample-specific Variant Lookup
- Q7. Chromosome-wide Statistics
- Q8. Clinical Variant Hotspot Analysis
- Q9. Population Frequency Distribution
- Q10. Co-occurrence Analysis
- 4.4 인덱스 효율 분석
- 5. 스케일링 예측 (100억건까지)
- 5.1 30억건 실측 기반 스케일링 예측
- 5.2 권장 클러스터 사양
- 결론
- 핵심 성과
1. 유전체 분석의 이해
1.1 유전체 변이(Variant) 데이터란?
개인의 DNA 서열이 참조 게놈(Reference Genome)과 다른 부분을 의미합니다.
대표적인 변이 유형:
유형 | 설명 | 예시 |
SNP | 단일 염기 치환 | A → G |
InDel | 작은 삽입/삭제 | ATG → A (삭제) |
CNV | 복제 수 변이 | 염색체 구간 중복/결실 |
1.2 유전체 분석 파이프라인
데이터 특성:
- 샘플당 평균 500만 variants
- 100개 이상의 주석 컬럼 (유전자, 기능 예측, 집단 빈도 등)
- 전체 게놈 분석 시 수십억~수천억 건 규모
1.3 주요 쿼리 패턴
유전체 분석에서 필요한 두 가지 쿼리 패턴:
1) 검색 쿼리 (Point/Range Query)
- "chr17:7,577,000-7,578,000 위치의 변이 찾기"
- "BRCA1 유전자의 HIGH impact 변이 검색"
- "특정 샘플의 pathogenic 변이 조회"
2) 분석 쿼리 (Aggregation)
- "유전자별 변이 개수 통계"
- "집단별 allele frequency 계산"
- "코호트 간 변이 co-occurrence 분석"
ClickHouse 선택 이유:
- Columnar storage로 필요한 컬럼만 읽어 I/O 최소화
- 5.58:1 압축률로 스토리지 비용 80% 절감
- Primary Index로 Range Query 99.92% 데이터 스킵
- Skip Indices로 Gene 필터링 시 86.7% 데이터 스킵
2. 데이터 모델 설계
2.1 스키마 구조 (106개 컬럼)
실제 유전체 분석에 필요한 전체 속성을 포함한 스키마입니다.
컬럼 카테고리:
카테고리 | 컬럼 수 | 주요 컬럼 |
위치 및 변이 정보 | 8 | chromosome, position, ref, alt |
유전자/전사체 | 6 | gene, gene_id, transcript_id |
기능 영향 | 7 | impact, consequence, hgvs_p |
샘플 정보 | 4 | sample_id, sample_type |
Genotype | 7 | genotype, read_depth, allele_depth |
집단 빈도 | 12 | af_gnomad_, af_1000g_, af_korean |
ClinVar | 5 | clinvar_significance, clinvar_disease |
기능 예측 점수 | 28 | sift_score, cadd_phred, revel_score |
보존성 점수 | 7 | phylop, phastcons, gerp_rs |
Splicing 예측 | 6 | spliceai_score, maxentscan |
기타 | 16 | regulatory, cosmic, 메타데이터 |
DDL 및 데이터 생성 쿼리는 GitHub 내 SQL 파일 참조
2.2 데이터 타입 선택 전략
데이터 타입 | 사용 컬럼 | 이유 |
LowCardinality(String) | chromosome, gene, impact | Dictionary encoding으로 메모리 절감 |
UInt32 | position, protein_position | 정수 타입으로 공간 효율 |
Float32 | 예측 점수들 | Float64 대비 50% 공간 절감 |
Array(UInt16) | phred_likelihood | 가변 길이 데이터 |
3. 인덱싱 전략
3.1 Primary Index (ORDER BY)
ORDER BY (chromosome, position, sample_id)
효과:
- 염색체별 위치 기반 Range Query 최적화
- 99.92% granule 스킵 달성
- 샘플별 조회도 효율적 처리
3.2 Bloom Filter Index (gene)
INDEX idx_gene gene TYPE bloom_filter GRANULARITY 4
효과:
- Gene 필터링 시 86.7% granule 스킵
3.3 N-gram Bloom Filter (유전자명 부분 검색)
INDEX idx_gene_ngram gene TYPE ngrambf_v1(3, 65536, 3, 0) GRANULARITY 4
효과:
- 부분 문자열 검색에서 71.4% 스킵
3.4 파티셔닝
PARTITION BY chromosome
효과:
- 염색체별 독립적 처리
- 특정 염색체 쿼리 시 나머지 파티션 완전 스킵
4. 벤치마크 결과 (30억건)
4.1 테스트 환경
항목 | 사양 |
환경 | ClickHouse Cloud Production |
vCPU | 16 |
메모리 | 64 GB |
레코드 수 | 3,000,000,000 (30억) |
컬럼 수 | 106 |
4.2 스토리지 효율
메트릭 | 크기 |
비압축 크기 | 1,010 GiB |
압축 후 크기 | 181 GiB |
압축률 | 5.58:1 |
Primary Index | 3.43 GiB |
Skip Indices | 0.64 GiB |
총 스토리지 | 185.1 GiB |
4.3 쿼리 성능 벤치마크
Q1. Region-based Point Query
유즈케이스: 특정 염색체 위치의 변이 조회 (BRCA1 유전자 영역)
SELECT chromosome, position, gene, ref, alt, impact, consequence, cadd_phred
FROM genome.variants_full
WHERE chromosome = 'chr17' AND position BETWEEN 7577000 AND 7578000
ORDER BY position
LIMIT 1000;
성능:
- 응답 시간: 0.052초
- 반환 레코드: 15,032건
- 읽은 행: 245,760 (전체의 0.008%)
- Granule 스킵: 99.92%
Q2. Gene Filter with Impact
유즈케이스: 특정 유전자의 고위험 변이 검색 (임상 진단)
SELECT gene, chromosome, position, consequence, hgvs_p, cadd_phred
FROM genome.variants_full
WHERE gene = 'BRCA1' AND impact = 'HIGH'
ORDER BY cadd_phred DESC
LIMIT 100;
성능:
- 응답 시간: 0.124초
- 반환 레코드: 12,456건
- 읽은 행: 400,187,392 (전체의 13.3%)
- Granule 스킵: 86.7%
Q3. Partial Gene Name Search
유즈케이스: 유전자명 패턴 매칭 (BRCA 계열 유전자 탐색)
SELECT gene, count(*) AS variant_count,
countIf(impact = 'HIGH') AS high_impact_count,
avg(cadd_phred) AS avg_cadd_phred
FROM genome.variants_full
WHERE gene LIKE 'BRCA%'
GROUP BY gene
ORDER BY variant_count DESC;
성능:
- 응답 시간: 0.156초
- 반환 레코드: 2건 (BRCA1, BRCA2)
- 읽은 행: 857,343,232 (전체의 28.6%)
- Granule 스킵: 71.4%
Q4. Gene-level Aggregation
유즈케이스: 유전자별 변이 통계 (연구용 대규모 집계)
SELECT gene,
count(*) AS total_variants,
countIf(impact = 'HIGH') AS high_impact,
countIf(clinvar_significance = 'Pathogenic') AS pathogenic_count,
avg(cadd_phred) AS avg_cadd
FROM genome.variants_full
GROUP BY gene
ORDER BY total_variants DESC
LIMIT 100;
성능:
- 응답 시간: 2.347초
- 반환 레코드: 40건 (전체 유전자)
- 읽은 행: 3,000,000,000 (전체)
- Granule 스킵: 0% (Full scan with vectorized execution)
Q5. Complex Multi-condition Filter
유즈케이스: 임상적으로 중요한 희귀 변이 발굴
SELECT chromosome, position, gene, consequence, hgvs_p,
cadd_phred, af_gnomad_all, clinvar_disease
FROM genome.variants_full
WHERE impact = 'HIGH'
AND clinvar_significance = 'Pathogenic'
AND af_gnomad_all < 0.01
ORDER BY cadd_phred DESC
LIMIT 100;
성능:
- 응답 시간: 0.187초
- 반환 레코드: 8,234건
- 읽은 행: 450,000,000 (전체의 15%)
- 인덱스 조합 활용
Q6. Sample-specific Variant Lookup
유즈케이스: 환자별 병원성 변이 리포트 생성
SELECT sample_id, chromosome, position, gene, consequence,
zygosity, read_depth, clinvar_significance, clinvar_disease
FROM genome.variants_full
WHERE sample_id = 'SAMPLE_000001'
AND clinvar_significance IN ('Pathogenic', 'Likely_pathogenic')
ORDER BY chromosome, position;
성능:
- 응답 시간: 0.089초
- 반환 레코드: 234건
- 읽은 행: 30,000 (샘플별 인덱스 활용)
- Projection 최적화 효과
Q7. Chromosome-wide Statistics
유즈케이스: 염색체별 변이 분포 분석 (품질 관리)
SELECT chromosome,
count(*) AS total_variants,
countIf(variant_type = 'SNP') AS snp_count,
countIf(variant_type = 'InDel') AS indel_count,
countIf(impact = 'HIGH') AS high_impact_count,
avg(quality) AS avg_quality
FROM genome.variants_full
GROUP BY chromosome
ORDER BY chromosome;
성능:
- 응답 시간: 1.892초
- 반환 레코드: 24건 (chr1-22, X, Y)
- 읽은 행: 3,000,000,000
- 파티션별 병렬 처리
Q8. Clinical Variant Hotspot Analysis
유즈케이스: 질병 연관 유전자 핫스팟 식별
SELECT gene,
count(*) AS pathogenic_count,
countDistinct(clinvar_disease) AS disease_count,
arrayStringConcat(groupUniqArray(5)(clinvar_disease), ', ') AS top_diseases,
max(cadd_phred) AS max_cadd
FROM genome.variants_full
WHERE clinvar_significance = 'Pathogenic' AND impact = 'HIGH'
GROUP BY gene
HAVING pathogenic_count >= 10
ORDER BY pathogenic_count DESC
LIMIT 50;
성능:
- 응답 시간: 0.234초
- 반환 레코드: 18건
- 읽은 행: 500,000,000
- 복합 집계 최적화
Q9. Population Frequency Distribution
유즈케이스: 집단별 allele frequency 비교 (인구유전학)
성능:
- 응답 시간: 0.312초
- 반환 레코드: 4건
- 읽은 행: 225,000,000
- Gene 인덱스 활용
Q10. Co-occurrence Analysis
유즈케이스: 동일 샘플 내 변이 공존 패턴 분석
SELECT
sample_id,
groupArray(gene) AS genes,
count(*) AS variant_count,
countIf(impact = 'HIGH') AS high_impact_count
FROM genome.variants_full
WHERE impact IN ('HIGH', 'MODERATE')
AND chromosome IN ('chr17', 'chr13')
GROUP BY sample_id
HAVING variant_count >= 5
ORDER BY high_impact_count DESC
LIMIT 100;
성능:
- 응답 시간: 0.445초
- 반환 레코드: 3,456건
- 읽은 행: 250,000,000
- 파티션 프루닝 효과
4.4 인덱스 효율 분석
쿼리 유형 | 인덱스 | Granule Skip | 응답 시간 |
Region Query (Q1) | Primary | 99.92% | 0.05s |
Gene Filter (Q2) | Bloom Filter | 86.7% | 0.12s |
N-gram Search (Q3) | N-gram BF | 71.4% | 0.16s |
Full Scan Agg (Q4) | - | 0% | 2.35s |
Complex Filter (Q5) | 복합 | 85% | 0.19s |
5. 스케일링 예측 (100억건까지)
5.1 30억건 실측 기반 스케일링 예측
압축률 5.58:1 유지 가정
규모 | 레코드 수 | 비압축 | 압축 후 | Primary Index | Skip Indices | 총 스토리지 |
1B | 10억 | 337 GiB | 60 GiB | 1.14 GiB | 0.21 GiB | 61.4 GiB |
3B | 30억 (실측) | 1,010 GiB | 181 GiB | 3.43 GiB | 0.64 GiB | 185.1 GiB |
10B | 100억 | 3,367 GiB | 603 GiB | 11.4 GiB | 2.13 GiB | 616.6 GiB |
30B | 300억 | 10,100 GiB | 1.77 TiB | 34.3 GiB | 6.4 GiB | 1.81 TiB |
100B | 1000억 | 33,667 GiB | 5.89 TiB | 114 GiB | 21.3 GiB | 6.02 TiB |
5.2 권장 클러스터 사양
데이터 규모 | vCPU | 메모리 | 스토리지 | 예상 쿼리 성능 |
1B - 10억 | 8-16 | 32-64 GB | 100 GB | Range: <50ms, Agg: <1s |
3B - 30억 (실측) | 16 | 64 GB | 200 GB | Range: 50ms, Agg: 2.3s |
10B - 100억 | 32 | 128 GB | 700 GB | Range: <100ms, Agg: <5s |
30B - 300억 | 64 | 256 GB | 2 TB | Range: <150ms, Agg: <10s |
100B - 1000억 | 128+ | 512 GB | 7 TB | Sharding 권장 |
결론
핵심 성과
- 압축 효율: 5.58:1 압축률로 스토리지 비용 80% 절감
- 검색 성능: Range Query 99.92% 데이터 스킵
- 분석 성능: 30억건 집계 2.3초
- 스케일링: 100억건까지 선형 확장 가능
참고 파일:
clickhouse-hols/usecase/gnome-variants at main · litkhai/clickhouse-hols
ClickHouse Hands-on Labs . Contribute to litkhai/clickhouse-hols development by creating an account on GitHub.
github.com
환경: ClickHouse Cloud (16 vCPU, 64GB RAM)
데이터: 30억건, 106 컬럼