안녕하세요 에이플랫폼 입니다.
오늘은 Docker 환경에서 SingleStore, Mysql, PostgreSQL을 밴치마킹 해보겠습니다.
현실적인 핀테크 스타일의 워크로드를 생성하고, 각 플랫폼이 과도한 조인, 롤링 윈도우 합계 및 핫 분석 쿼리를 어떻게 처리하는지 측정해보겠습니다.
현실적이고 동등한 입장을 유지하기 위해 테스트 중인 세 가지 플랫폼 모두에서 사용할 수 있는 프로젝트와 워크로드를 만들었습니다.
구축한 벤치마크 프로젝트는 Turborepo를 기반으로 하며 여러 애플리케이션과 패키지를 포함합니다.
프로젝트에는 아래의 내용이 포함됩니다.
응용 프로그램
- ./apps/db Docker 컨테이너를 실행하기 위한 애플리케이션입니다.
- ./apps/data-generator Node.js 데이터를 생성하여 데이터베이스에 로드하고 인덱스를 생성하기 위한 응용 프로그램입니다.
- ./apps/client Next.js 클라이언트를 시작하고 쿼리를 실행하는 응용 프로그램 입니다.
패키지
- ./packages/singlestore SingleStore 이미지에 연결된 Drizzle 인스턴스
- ./packages/mysql MySQL 이미지에 연결된 Drizzle 인스턴스
- ./packages/postgres PostgreSQL 이미지에 연결된 Drizzle 인스턴스
Docker 이미지
- SingleStore. ghcr.io/singlestore-labs/singlestoredb-dev:latest
- MySQL. mysql:latest
- Postgres. postgres:latest
이번 글의 밴치마크는 SingleStore Git hub의 docker-benchmarking-battle 저장소를 복제하고, README.md 를 따라 프로젝트를 로컬에서 실행할 수 있습니다.
밴치마킹에 사용한 데이터 스키마와 시나리오를 소개하겠습니다.
데이터 스키마
세 데이터베이스 모두 정확히 동일한 스키마와 데이터 볼륨을 공유합니다.
1개의 CSV 파일당 100만 개의 레코드가 포함되어 있습니다.
users 데이터 예시 (1,000,000 row, 1 csv)
1,Lew_McKenzie@gmail.com,Wallace Paucek,2025-05-23 05:27:13,2025-05-23 05:27:13
2,Kariane_Ebert@yahoo.com,Vivian Howell,2025-05-23 05:27:13,2025-05-23 05:27:13
3,Maximillia.Kassulke@gmail.com,Candace Jaskolski,2025-05-23 05:27:13,2025-05-23 05:27:13
...
999998,Demarco50@gmail.com,Mindy Gleichner,2025-05-23 05:27:13,2025-05-23 05:27:13
999999,Collin.Carroll@hotmail.com,Marie Ziemann,2025-05-23 05:27:13,2025-05-23 05:27:13
1000000,Bernadette_Barrows@hotmail.com,Patti Cartwright,2025-05-23 05:27:13,2025-05-23 05:27:13
accounts 데이터 예시
1,66579,854.43,2025-05-23 05:27:13,2025-05-23 05:27:13
2,37791,808.57,2025-05-23 05:27:13,2025-05-23 05:27:13
3,640582,315.94,2025-05-23 05:27:13,2025-05-23 05:27:13
...
9999998,385103,989.82,2025-05-23 05:27:13,2025-05-23 05:27:13
9999999,70981,632.24,2025-05-23 05:27:13,2025-05-23 05:27:13
10000000,290693,944.65,2025-05-23 05:27:13,2025-05-23 05:27:1
transactions 데이터 예시
1,9362328,6721922,1,3,412.51,2025-05-23 05:27:13
2,1914157,8069260,2,1,267.82,2025-05-23 05:27:13
3,6074342,1461115,1,2,429.78,2025-05-23 05:27:13
...
99999998,5199513,2180298,1,2,286.39,2025-05-23 05:27:13
99999999,2458298,3270926,2,2,645.69,2025-05-23 05:27:13
100000000,9600327,7657710,1,3,823.70,2025-05-23 05:27:13
밴치마크 시나리오
1. Total transaction volume (last 30 days)
첫번째로, 전체 시스템에서 지난 30일 이내에 이루어진 모든 성공한 트랜잭션의 합계를 계산하고, transactions 및 transaction_statuses테이블을 조인하고, status = "success" 및 createdAt > NOW() - 30 days를 필터링합니다.
이러한 유형의 쿼리는 동적 시간 창에 대한 합계를 자주 계산해야 하는 재무 대시보드 및 수익 보고 도구에서 사용할 수 있습니다.
TypeScript를 사용하면 쿼리는 다음과 같습니다.
// ./packages/singlestore/transaction/get-sum.ts
export async function getTransactionsSum()
{
const cutoffDate = subDays(new Date(), 30);
const result = await singlestore
.select({ sum: sum(transactionsTable.amount) })
.from(transactionsTable)
.innerJoin(transactionStatusesTable, eq(transactionStatusesTable.id, transactionsTable.statusId))
.where(and(gt(transactionsTable.createdAt, cutoffDate), eq(transactionStatusesTable.name, "success")));
return result;
}
아래의 결과는 SingleStore공식 블로그에 올라온 결과 입니다.
2. Top transfer recipients
다음으로, 각 계정이 송금 받은 횟수를 계산하여 성공적인 송금의 가장 일반적인 수신자를 찾는 또 다른 쿼리를 살펴보고 transactions, transaction_types 및 transaction_statuses 테이블을 조인합니다 .
type = "transfer" 및 status = "success"에 대한 필터는 각 'accountIdTo'가 전송을 받은 횟수를 계산한 다음 transferCount를 기준으로 정렬됩니다.
이러한 유형의 쿼리는 핀테크 앱에서 VIP 수신자, 사기 패턴 또는 빈번한 비즈니스 수취인을 감지하는 데 유용할 수 있습니다.
TypeScript로 끓일 때 결과 쿼리는 다음과 같습니다.
// ./packages/singlestore/account/list-top-recipients.ts
export type ListTopRecipientsParams = {
limit?: number;
};
export async function listTopRecipients(params: ListTopRecipientsParams) {
const { limit = 10 } = params;
const result = await singlestore
.select({
accountIdTo: transactionsTable.accountIdTo,
transferCount: count(transactionsTable.id).as("transferCount"),
})
.from(transactionsTable)
.innerJoin(transactionTypesTable, eq(transactionTypesTable.id, transactionsTable.typeId))
.innerJoin(transactionStatusesTable, eq(transactionStatusesTable.id, transactionsTable.statusId))
.where(and(eq(transactionTypesTable.name, "transfer"), eq(transactionStatusesTable.name, "success")))
.groupBy(transactionsTable.accountIdTo)
.orderBy(desc(sql`transferCount`))
.limit(limit);
return result;
}
아래의 결과는 SingleStore공식 블로그에 올라온 결과 입니다.
3. Total transaction volume (last 30 days)
마지막으로, 지난 7일 동안의 최근 트랜잭션을 검색하고 다중 테이블 조인을 사용하여 연결된 사용자 및 계정 정보를 포함하는 쿼리를 실행합니다.
사용자, 계정, 트랜잭션 및 transaction_types 테이블을 조인하여 사용자 이름, 계정 ID, 금액 및 트랜잭션 유형을 포함하여 지난 7일 동안의 트랜잭션을 검색합니다.
이 유형의 쿼리는 실시간 활동 피드 또는 최근 거래 페이지를 복제하며, 이는 뱅킹 앱에서 일반적이며 SingleStore의 스위트 스폿입니다.
쿼리를 TypeScript로 구문 분석하면 결과 코드는 다음과 같습니다.
// ./packages/singlestore/transaction/list-recent-with-info.ts
export async function listRecentTransactionsWithInfo() {
const cutoffDate = subDays(new Date(), 7);
const result = await singlestore
.select({
userId: usersTable.id,
name: usersTable.name,
accountId: accountsTable.id,
amount: transactionsTable.amount,
type: transactionTypesTable.name,
createdAt: transactionsTable.createdAt,
})
.from(usersTable)
.innerJoin(accountsTable, eq(accountsTable.userId, usersTable.id))
.innerJoin(transactionsTable, eq(transactionsTable.accountIdFrom, accountsTable.id))
.innerJoin(transactionTypesTable, eq(transactionTypesTable.id, transactionsTable.typeId))
.where(gte(transactionsTable.createdAt, cutoffDate))
.orderBy(desc(transactionsTable.createdAt))
.limit(100);
return result;
}
아래의 결과는 SingleStore공식 블로그에 올라온 결과 입니다.
직접 실행해보기
SingleStore Github: https://github.com/singlestore-labs/demo-docker-benchmarking-battle
GitHub - singlestore-labs/demo-docker-benchmarking-battle
Contribute to singlestore-labs/demo-docker-benchmarking-battle development by creating an account on GitHub.
github.com
위의 깃허브 주소에서 레포지토리를 복제후 ReadMe를 따라서 직접 로컬에서 실행해 보실 수 있습니다.
그리고 여기에서 직접 라이브 데모를 실행해 볼 수 있습니다.
https://demo-docker-benchmarking-battle.vercel.app/
이번 벤치마크 테스트 결과를 통해 SingleStore가 탁월한 성능과 확장성을 갖춘 데이터베이스임을 다시 한번 확인할 수 있었습니다.
대량의 데이터를 빠르게 처리하고, 효율적인 운영을 원하는 기업이라면 SingleStore가 최고의 선택이 될 것입니다.
앞으로도 더욱 강력한 기능과 최적화된 성능을 제공할 SingleStore의 발전을 기대해주세요!
'SingleStoreDB > 엔지니어링' 카테고리의 다른 글
SingleStore Notebooks, 시간 관리: Cron Scheduling 활용법 (0) | 2025.05.07 |
---|---|
SingleStore MCP Server with Claude (0) | 2025.04.24 |
SingleStore - Apache Flink를 사용한 실시간 스트리밍 파이프라인 구축 (0) | 2025.04.07 |
SingleStore 파이프라인을 활용한 S3 Access Log 데이터 실시간 분석 (0) | 2025.03.20 |
SingleStore로 구현한 실시간 자동완성과 오타 허용 (0) | 2025.03.14 |