Search

SingleStore를 이용한 Graph Query 성능 비교

문서번호 : 11-4343546

Document Information

최초 작성일 : 2026.03.23
최종 수정일 : 2026.03.23
이 문서는 아래 버전을 기준으로 작성되었습니다.
SinglestoreDB : 9.0.22
PuppyGraph: 0.116
Neo4j(community edition): 5.23

개요

SingleStore빠른 SQL 분석에 강점을 가진 데이터 플랫폼이고, PuppyGraph는 그 위에 그래프 탐색 계층을 추가합니다. 이 데모에서는 원본 데이터는 SingleStore에 그대로 두고 PuppyGraph를 결합해, 별도 ETL 없이 관계 탐색과 multi-hop 분석을 수행하는 방법을 보여주고자 합니다. 이 과정에서 SingleStore 단독 구성, SingleStore + PuppyGraph 조합, 그리고 GraphDB로 널리 알려진 Neo4j를 대상으로 성능 비교도 함께 진행하려고 합니다.

PuppyGraph란?

PuppyGraph은 기존 관계형 데이터 저장소나 데이터 레이크를 직접 연결해, 별도 ETL 없이 그래프처럼 질의할 수 있게 해주는 zero-ETL graph analytics engine입니다. 전통적인 Graph DB처럼 데이터를 별도로 복제해 저장하는 대신, 기존 데이터 소스를 그대로 활용하면서 그 위에 그래프 모델을 정의해 관계 탐색과 multi-hop 분석을 수행할 수 있습니다.

사기 탐지 데모

사기 탐지나 리스크 분석에서는 하나의 계정만 보는 것이 아니라, 여러 계정이 같은 디바이스, IP, 결제수단, 주소를 공유하는지와 같은 관계를 함께 봐야 하는 경우가 많습니다. 이런 분석은 SQL로도 가능하지만, 탐색 범위가 넓어지고 hop 수가 증가할수록 쿼리 가독성과 유지보수성이 떨어질 수 있습니다.
이 데모는 이러한 관계형 데이터를 SingleStore에 그대로 유지한 채, PuppyGraph를 통해 그래프 관점에서 더 직관적으로 탐색하는 방식을 보여주는 것을 목표로 합니다.

데모 데이터

테이블
Row 수
설명
accounts
700,000
결제 서비스를 사용하는 사용자 계정 정보
devices
500,000
계정이 로그인하거나 결제할 때 사용하는 기기 정보
ips
2,000,000
계정이 접속할 때 사용하는 IP 정보
merchants
60,000
거래가 발생하는 가맹점 정보
account_device_edge
1,800,000
어떤 계정이 어떤 기기를 사용했는지 나타내는 연결 정보
account_ip_edge
6,500,000
어떤 계정이 어떤 IP를 사용했는지 나타내는 연결 정보
transactions
24,000,000
실제 결제/거래 이벤트 정보
chargebacks
200,000
사후에 분쟁이나 환불로 이어진 거래 정보

사기 탐지 데모

이 데모에서는 Cypher를 사용해 Account, Device, IP, 거래 간의 연결 관계를 탐색하고, 이를 바탕으로 사기 의심 패턴을 분석합니다.

Query 1

이 쿼리는 의심 Account 하나에서 시작해서, 같은 Device를 사용한 다른 Account들을 바로 보여주는 가장 기본적인 1-hop 쿼리 입니다. PuppyGraph Ui를 통해 쿼리에 대한 Graph를 확인할 수 있습니다.
MATCH (seed:Account {account_id: 34})-[:USED_DEVICE]->(d:Device) WITH seed, d ORDER BY toInteger(d.device_id) LIMIT 1 MATCH (seed)-[r1:USED_DEVICE]->(d)<-[r2:USED_DEVICE]-(peer:Account) WHERE peer.account_id <> seed.account_id WITH seed, r1, d, r2, peer ORDER BY toInteger(peer.account_id) LIMIT 15 RETURN seed, r1, d, r2, peer;
SQL
복사

Query 2

Query 1이 의심 Account과 같은 Deivce를 사용한 Account를 확인하는 기본적인 조사라면, 이 쿼리는 그 Account들이 또 어떤 Device를 사용했고, 그 Device를 통해 누구와 더 연결되는지까지 한 단계 더 확장해서 보여주는 쿼리 입니다.
MATCH (seed:Account {account_id: 34})-[:USED_DEVICE]->(d1:Device) WITH seed, d1 ORDER BY toInteger(d1.device_id) LIMIT 1 MATCH (seed)-[r1:USED_DEVICE]->(d1)<-[r2:USED_DEVICE]-(hop1:Account) WHERE hop1.account_id <> seed.account_id WITH seed, d1, r1, r2, hop1 ORDER BY toInteger(hop1.account_id) LIMIT 6 MATCH (hop1)-[r3:USED_DEVICE]->(d2:Device)<-[r4:USED_DEVICE]-(hop2:Account) WHERE d2.device_id <> d1.device_id AND hop2.account_id <> seed.account_id AND hop2.account_id <> hop1.account_id RETURN seed, r1, d1, r2, hop1, r3, d2, r4, hop2 LIMIT 30;
SQL
복사

Query 3

이 쿼리는 의심 Account과 같은 Device를 사용한 Account를 찾은 뒤, 그 Account들이 최근 merchant랑 실제 Transaction을 일으켰는지까지 같이 보여줍니다. 즉 단순 연결관계가 아니라, 연결된 계정에서 실제 위험 거래가 발생했는지를 한 화면에서 확인하는 예시 입니다.
MATCH (seed:Account {account_id: 34})-[r1:USED_DEVICE]->(d:Device) WITH seed, r1, d ORDER BY toInteger(d.device_id) LIMIT 1 MATCH (d)<-[r2:USED_DEVICE]-(peer:Account) WHERE peer.account_id <> seed.account_id WITH seed, r1, d, r2, peer ORDER BY toInteger(peer.account_id) LIMIT 4 MATCH (peer)-[r3:PLACED]->(tx:Transaction)-[r4:AT]->(m:Merchant) WHERE tx.ts >= datetime('2026-03-15T12:00:00') - duration('P7D') AND tx.status = 'SETTLED' AND m.risk_score >= 80 WITH seed, r1, d, r2, peer, r3, tx, r4, m ORDER BY tx.ts DESC LIMIT 12 RETURN seed, r1, d, r2, peer, r3, tx, r4, m;
SQL
복사

Benchmark (SingleStore + PuppyGrpah VS Neo4j)

본 데모에서는 동일한 데이터셋을 기반으로, SingleStoreSingleStore + PuppyGraph, Neo4j 의 성능을 비교했습니다. SIngleStore의 경우 SQLSinlgeStore + PuppyGraph, Neo4j는 Cypher을 사용하여 쿼리를 진행했습니다.
테스트 환경은 다음과 같습니다.
SingleStore: 8 vCPU, 64 GB RAM (1 MA + 1 LF)
SingleStore + PuppyGraph: 8 vCPU, 64 GB RAM (1 MA + 1 LF)
Neo4j: 8 vCPU, 64 GB RAM
벤치마크 쿼리 파일
neo4j_puppygraph.cypher
15.2 KiB
singlestore.sql
17.8 KiB

Bench 1. 전체 거래에서 먼저 수상한 후보를 줄이는 방식

이 벤치마크는 전체 거래 데이터를 대상으로, 최근 거래인지, 위험 merchant와 관련이 있는지, 거래 금액이 큰지, chargeback 이력이 있는지 등의 조건으로 먼저 의심 후보를 추려낸 뒤, 그 후보들 사이의 연결 관계를 추가로 탐색하는 방식의 성능을 비교한 결과입니다.
Bench 1의 경우 대부분 앞단에서 filteringaggregation을 진행하는 시나리오 였습니다. SinlgeStore를 사용 하는게 가장 성능이 좋았고 PuppyGraph + SingleStore역시 Neo4j보다는 성능이 좋게 나왔습니다.
ID
분석 시나리오
SingleStore
PuppyGraph
Neo4j
해석
1
최근 high-risk 거래가 많은 계정은?
81ms
2240.1 ms
5166.0 ms
앞단에서 fact filtering과 aggregation 비중이 큼
2
최근 cross-border 고위험 거래 계정은?
231.4ms
3591.8 ms
20686.8 ms
Recent / risk / filter / aggregation workload 비중이 큼
3
여러 의심 계정과 연결된 peer 중 chargeback 신호가 강한 쪽은?
65.3ms
227.9 ms
416.3 ms
단순 peer 확장보다 chargeback rollup 연산 비중이 큼
4
최근 chargeback 계정 중심 연결 분석
255ms
3751.2 ms
2825.3 ms
Chargeback와 연결된 그래프 탐색 비용 비중이 상대적으로 큼

Bench 2. 의심 계정에서 시작해 주변 연결을 바로 파고드는 방식

이미 의심스러운 계정 하나 또는 몇 개를 Seed로 잡고, 같은 Device/IP를 쓰는 Peer를 먼저 넓혀 보는 유형입니다.
Bench 2의 경우 작은 Seed에서 시작해 Local Neighborhood를 빠르게 확장하는 Graph Traversal 성능 이 더 중요한 시나리오 입니다. 따라서 Neo4j가 더 좋은 결과가 나왔습니다.
ID
분석 시나리오
SingleStore
PuppyGraph
Neo4j
해석
5
의심 계정의 peer 네트워크 빠른 확장
197ms
282.8 ms
178.4 ms
Graph neighborhood 확장이 앞단에 있어 Neo4j가 더 유리
6
Known bad account 기준 3-hop 조사
94.7ms
1679.1 ms
11.3 ms
Seed-first 3-hop 조사형 시나리오에서는 Neo4j 강점이 매우 크게 나타남

Bench 3. 먼저 의심 계정을 추린 뒤, 필요한 범위까지만 더 깊게 따라가는 방식

Bench 3Bench 1처럼 먼저 의심 계정 후보를 줄인 뒤, shared deviceshared IP 같은 연결 관계를 몇 단계 더 따라가는 유형시나리오 입니다. 그래프를 무한정 확장하지 않고, 각 단계마다 후보 수를 제한하면서 필요한 범위까지만 탐색합니다.
Bench 3의 경우 먼저 거래 조건으로 볼 대상을 줄이고, 그 집합에서만 필터링 및 집계하는 방식이어서 SingleStore의 성능이 가장 좋았고 SingleStore + PuppyGraphNeo4j보다 더 좋은 결과를 보여줬습니다.
ID
분석 시나리오
SingleStore
PuppyGraph
Neo4j
해석
7
의심 계정 후보를 추린 뒤 3-hop 까지 확장
1871.4ms
2027.4 ms
5181.6 ms
3단계까지 확장하더라도 먼저 볼 계정을 줄여 놓음
8
의심 계정 후보를 추린 뒤 8-hop 까지 확장
144.7ms
2793.2 ms
20619.9 ms
더 깊게 보더라도 필요한 범위까지만 제한적으로 확장하는 조사 방식

벤치 마크 결과 그래프 종합

결론

운영 애플리케이션처럼 반복적으로 실행되는 고정형 쿼리와, 대량 데이터에 대한 집계·필터링이 먼저 수행되는 fraud 분석 시나리오에서는 SingleStore가 가장 빠른 성능을 보였습니다.
관계 탐색이 필요하지만 별도의 GraphDB로 데이터를 복제하거나 ETL 파이프라인을 추가하고 싶지 않은 경우에는, 원본 데이터를 SingleStore에 그대로 두고 PuppyGraph를 결합하는 방식이 실용적이었습니다. 즉, SQL 중심의 운영 환경유지하면서도 비교적 간단한 Graph Query와 조사형 분석을 유연하게 추가할 수 있습니다.
집계나 대규모 Fact Filtering보다, 소수의 의심 계정에서 시작해 주변 연결을 빠르게 확장하는 순수 Graph-First 탐색 시나리오에서는 Neo4j가 유리한 모습을 보였습니다.
따라서 실제 서비스 관점에서는 특정 Graph Traversal 성능만을 위해 전체 데이터 플랫폼을 별도로 가져가기보다, 대부분의 운영 쿼리와 분석 워크로드를 함께 처리할 수 있는 SingleStore로 구성하고 필요시 PuppyGraph를 통한 Graph Query를 진행하는 것이 효율적 이라고 볼 수 있습니다.

References

History

일자
작성자
비고
2026.03.23
hoon
최초 작성
2026.03.25
jwy
벤치별 그래프 추가