-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MySQL과 mongoDB 성능 비교를 위한 코드 작성 (#193)
* chore: mysql과 mongoDB 성능 비교를 위한 코드 작성 * fix: 통합 테스트 코드 삭제
- Loading branch information
1 parent
afa2e9f
commit 05f4fb7
Showing
10 changed files
with
402 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export const MOCK_CONFIG = { | ||
ITERATIONS: { | ||
DEFAULT: 1000, | ||
CONCURRENT: 500, | ||
}, | ||
TEST_PREFIX: { | ||
SPACE: 'test-space-', | ||
NOTE: 'test-note-', | ||
CONCURRENT: 'concurrent-test-space-', | ||
}, | ||
} as const; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { MockNote } from '../types/performance.types'; | ||
|
||
export const noteMockData: MockNote[] = [ | ||
{ | ||
id: 'c1ddbb14-689a-49ac-a2fc-a14aebb1c4ed', | ||
userId: 'test-user-id', | ||
name: 'test-name', | ||
content: | ||
'AoIB+Ia//AoABwDujav1AwAGAQD4hr/8CgAEhPiGv/wKBAPthYyB+Ia//AoFAoT4hr/8CgcG7Iqk7Yq4h+6Nq/UDAAMJcGFyYWdyYXBoBwD4hr/8CgoGAQD4hr/8CgsDgfiGv/wKCgEABIH4hr/8Cg8BgfiGv/wKDgKE+Ia//AoWA+yXhIH4hr/8ChcChPiGv/wKGQPssq2B+Ia//AoaA4T4hr/8Ch0H64KY6rKMIIH4hr/8CiAChPiGv/wKIgTquLQggfiGv/wKJASE+Ia//AooA+usuIH4hr/8CikChPiGv/wKKwPsnpCB+Ia//AosAYT4hr/8Ci0D7Je0gfiGv/wKLgGE+Ia//AovA...', // Base64 encoded content | ||
createdAt: new Date(), | ||
updatedAt: new Date(), | ||
}, | ||
{ | ||
id: 'a4ac29f1-0504-43f4-b087-f47cf99b8186', | ||
userId: 'test-user-id', | ||
name: 'test-name', | ||
content: 'Different base64 encoded content...', | ||
createdAt: new Date(), | ||
updatedAt: new Date(), | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { MockSpace } from '../types/performance.types'; | ||
|
||
export const spaceMockData: MockSpace[] = [ | ||
{ | ||
id: '69bd78b6-0755-4370-be44-3ab0adab011a', | ||
userId: 'test-user-id', | ||
name: 'test', | ||
edges: JSON.stringify({ | ||
u7c2xras28c: { | ||
from: '69bd78b6-0755-4370-be44-3ab0adab011a', | ||
to: '65ol60chol8', | ||
}, | ||
an5uhqliqpm: { | ||
from: '69bd78b6-0755-4370-be44-3ab0adab011a', | ||
to: 'ousnj3faubc', | ||
}, | ||
}), | ||
nodes: JSON.stringify({ | ||
'69bd78b6-0755-4370-be44-3ab0adab011a': { | ||
id: '69bd78b6-0755-4370-be44-3ab0adab011a', | ||
x: 0, | ||
y: 0, | ||
type: 'head', | ||
name: 'test space', | ||
src: '69bd78b6-0755-4370-be44-3ab0adab011a', | ||
}, | ||
'65ol60chol8': { | ||
id: '65ol60chol8', | ||
type: 'note', | ||
x: 283.50182393227146, | ||
y: -132.99774870089817, | ||
name: 'note', | ||
src: 'c1ddbb14-689a-49ac-a2fc-a14aebb1c4ed', | ||
}, | ||
}), | ||
createdAt: new Date(), | ||
updatedAt: new Date(), | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { | ||
Entity, | ||
Column, | ||
PrimaryGeneratedColumn, | ||
CreateDateColumn, | ||
UpdateDateColumn, | ||
} from 'typeorm'; | ||
|
||
@Entity('notes') | ||
export class Note { | ||
@PrimaryGeneratedColumn('uuid') | ||
id: string; | ||
|
||
@Column({ type: 'varchar', length: 255, nullable: false }) | ||
userId: string; | ||
|
||
@Column({ type: 'varchar', length: 255, nullable: false }) | ||
name: string; | ||
|
||
@Column({ type: 'text', nullable: true, default: null }) | ||
content: string | null; | ||
|
||
@CreateDateColumn({ type: 'timestamp' }) | ||
createdAt: Date; | ||
|
||
@UpdateDateColumn({ type: 'timestamp' }) | ||
updatedAt: Date; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { | ||
Entity, | ||
Column, | ||
PrimaryGeneratedColumn, | ||
CreateDateColumn, | ||
UpdateDateColumn, | ||
Index, | ||
} from 'typeorm'; | ||
|
||
@Entity('spaces') | ||
export class Space { | ||
@PrimaryGeneratedColumn('uuid') | ||
id: string; | ||
|
||
@Column({ type: 'varchar', length: 255, nullable: true, default: null }) | ||
@Index() | ||
parentSpaceId: string | null; | ||
|
||
@Column({ type: 'varchar', length: 255, nullable: false }) | ||
userId: string; | ||
|
||
@Column({ type: 'varchar', length: 255, nullable: false }) | ||
name: string; | ||
|
||
@Column({ type: 'text', nullable: false }) | ||
edges: string; | ||
|
||
@Column({ type: 'text', nullable: false }) | ||
nodes: string; | ||
|
||
@CreateDateColumn({ type: 'timestamp' }) | ||
createdAt: Date; | ||
|
||
@UpdateDateColumn({ type: 'timestamp' }) | ||
updatedAt: Date; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
import { Controller, Get, Logger } from '@nestjs/common'; | ||
import { TestService } from './test.service'; | ||
import { spaceMockData } from './mock/space.mock.data'; | ||
import { noteMockData } from './mock/note.mock.data'; | ||
|
||
interface PerformanceResult { | ||
mysqlDuration: number; | ||
mongoDuration: number; | ||
difference: number; | ||
} | ||
|
||
@Controller('test') | ||
export class TestController { | ||
private readonly logger = new Logger(TestController.name); | ||
|
||
constructor(private readonly testService: TestService) {} | ||
|
||
@Get('read/space') | ||
async testSpaceReadPerformance() { | ||
this.logger.log('Testing read performance for Space.'); | ||
const iterations = 1000; | ||
|
||
const mysqlStartTime = process.hrtime(); | ||
for (let i = 0; i < iterations; i++) { | ||
await this.testService.findSpaceByIdSQL(spaceMockData[0].id); | ||
} | ||
const mysqlEndTime = process.hrtime(mysqlStartTime); | ||
const mysqlDuration = (mysqlEndTime[0] * 1e9 + mysqlEndTime[1]) / 1e6; | ||
|
||
const mongoStartTime = process.hrtime(); | ||
|
||
for (let i = 0; i < iterations; i++) { | ||
await this.testService.findSpaceByIdMongo(spaceMockData[0].id); | ||
} | ||
|
||
const mongoEndTime = process.hrtime(mongoStartTime); | ||
const mongoDuration = (mongoEndTime[0] * 1e9 + mongoEndTime[1]) / 1e6; | ||
|
||
this.logger.log('Read performance test for Space completed.', { | ||
mysqlDuration, | ||
mongoDuration, | ||
difference: Math.abs(mysqlDuration - mongoDuration), | ||
}); | ||
|
||
return { | ||
mysqlDuration, | ||
mongoDuration, | ||
difference: Math.abs(mysqlDuration - mongoDuration), | ||
}; | ||
} | ||
|
||
@Get('read/note') | ||
async testNoteReadPerformance() { | ||
this.logger.log('Testing read performance for Note.'); | ||
const iterations = 1000; | ||
|
||
const mysqlStartTime = process.hrtime(); | ||
for (let i = 0; i < iterations; i++) { | ||
await this.testService.findNoteByIdSQL(noteMockData[0].id); | ||
} | ||
const mysqlEndTime = process.hrtime(mysqlStartTime); | ||
const mysqlDuration = (mysqlEndTime[0] * 1e9 + mysqlEndTime[1]) / 1e6; | ||
|
||
const mongoStartTime = process.hrtime(); | ||
for (let i = 0; i < iterations; i++) { | ||
await this.testService.findNoteByIdMongo(noteMockData[0].id); | ||
} | ||
const mongoEndTime = process.hrtime(mongoStartTime); | ||
const mongoDuration = (mongoEndTime[0] * 1e9 + mongoEndTime[1]) / 1e6; | ||
|
||
this.logger.log('Read performance test for Note completed.', { | ||
mysqlDuration, | ||
mongoDuration, | ||
difference: Math.abs(mysqlDuration - mongoDuration), | ||
}); | ||
|
||
return { | ||
mysqlDuration, | ||
mongoDuration, | ||
difference: Math.abs(mysqlDuration - mongoDuration), | ||
}; | ||
} | ||
|
||
@Get('write/space') | ||
async testSpaceWritePerformance() { | ||
this.logger.log('Testing write performance for Space.'); | ||
const iterations = 1000; | ||
const testData = Array(iterations) | ||
.fill(null) | ||
.map((_, index) => ({ | ||
...spaceMockData[0], | ||
id: `test-space-${index}`, | ||
})); | ||
|
||
const mysqlStartTime = process.hrtime(); | ||
for (const data of testData) { | ||
await this.testService.createSpaceSQL(data); | ||
} | ||
const mysqlEndTime = process.hrtime(mysqlStartTime); | ||
const mysqlDuration = (mysqlEndTime[0] * 1e9 + mysqlEndTime[1]) / 1e6; | ||
|
||
const mongoStartTime = process.hrtime(); | ||
for (const data of testData) { | ||
await this.testService.createSpaceMongo(data); | ||
} | ||
const mongoEndTime = process.hrtime(mongoStartTime); | ||
const mongoDuration = (mongoEndTime[0] * 1e9 + mongoEndTime[1]) / 1e6; | ||
|
||
this.logger.log('Write performance test for Space completed.', { | ||
mysqlDuration, | ||
mongoDuration, | ||
difference: Math.abs(mysqlDuration - mongoDuration), | ||
}); | ||
|
||
return { | ||
mysqlDuration, | ||
mongoDuration, | ||
difference: Math.abs(mysqlDuration - mongoDuration), | ||
}; | ||
} | ||
|
||
@Get('write/note') | ||
async testNoteWritePerformance() { | ||
this.logger.log('Testing write performance for Note.'); | ||
const iterations = 1000; | ||
const testData = Array(iterations) | ||
.fill(null) | ||
.map((_, index) => ({ | ||
...noteMockData[0], | ||
id: `test-note-${index}`, | ||
})); | ||
|
||
const mysqlStartTime = process.hrtime(); | ||
for (const data of testData) { | ||
await this.testService.createNoteSQL(data); | ||
} | ||
const mysqlEndTime = process.hrtime(mysqlStartTime); | ||
const mysqlDuration = (mysqlEndTime[0] * 1e9 + mysqlEndTime[1]) / 1e6; | ||
|
||
const mongoStartTime = process.hrtime(); | ||
for (const data of testData) { | ||
await this.testService.createNoteMongo(data); | ||
} | ||
const mongoEndTime = process.hrtime(mongoStartTime); | ||
const mongoDuration = (mongoEndTime[0] * 1e9 + mongoEndTime[1]) / 1e6; | ||
|
||
this.logger.log('Write performance test for Note completed.', { | ||
mysqlDuration, | ||
mongoDuration, | ||
difference: Math.abs(mysqlDuration - mongoDuration), | ||
}); | ||
|
||
return { | ||
mysqlDuration, | ||
mongoDuration, | ||
difference: Math.abs(mysqlDuration - mongoDuration), | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { TypeOrmModule } from '@nestjs/typeorm'; | ||
import { MongooseModule } from '@nestjs/mongoose'; | ||
import { TestController } from './test.controller'; | ||
import { TestService } from './test.service'; | ||
import { Space as SpaceEntity } from './space.test.entity'; | ||
import { Note as NoteEntity } from './note.test.entity'; | ||
import { SpaceDocument, SpaceSchema } from 'src/space/space.schema'; | ||
import { NoteDocument, NoteSchema } from 'src/note/note.schema'; | ||
|
||
@Module({ | ||
imports: [ | ||
TypeOrmModule.forFeature([SpaceEntity, NoteEntity]), | ||
MongooseModule.forFeature([ | ||
{ name: SpaceDocument.name, schema: SpaceSchema }, | ||
{ name: NoteDocument.name, schema: NoteSchema }, | ||
]), | ||
], | ||
controllers: [TestController], | ||
providers: [TestService], | ||
exports: [TestService], | ||
}) | ||
export class TestModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { InjectRepository } from '@nestjs/typeorm'; | ||
import { Repository } from 'typeorm'; | ||
import { InjectModel } from '@nestjs/mongoose'; | ||
import { Model } from 'mongoose'; | ||
import { Space as SpaceEntity } from './space.test.entity'; | ||
import { Note as NoteEntity } from './note.test.entity'; | ||
import { SpaceDocument } from 'src/space/space.schema'; | ||
import { NoteDocument } from 'src/note/note.schema'; | ||
|
||
@Injectable() | ||
export class TestService { | ||
constructor( | ||
@InjectRepository(SpaceEntity) | ||
private spaceRepository: Repository<SpaceEntity>, | ||
@InjectRepository(NoteEntity) | ||
private noteRepository: Repository<NoteEntity>, | ||
@InjectModel(SpaceDocument.name) | ||
private spaceModel: Model<SpaceDocument>, | ||
@InjectModel(NoteDocument.name) | ||
private noteModel: Model<NoteDocument>, | ||
) {} | ||
|
||
async findSpaceByIdSQL(id: string) { | ||
return this.spaceRepository.findOne({ where: { id } }); | ||
} | ||
|
||
async findNoteByIdSQL(id: string) { | ||
return this.noteRepository.findOne({ where: { id } }); | ||
} | ||
|
||
async createSpaceSQL(data: any) { | ||
const space = this.spaceRepository.create(data); | ||
return this.spaceRepository.save(space); | ||
} | ||
|
||
async createNoteSQL(data: any) { | ||
const note = this.noteRepository.create(data); | ||
return this.noteRepository.save(note); | ||
} | ||
|
||
async findSpaceByIdMongo(id: string) { | ||
return this.spaceModel.findOne({ id }).exec(); | ||
} | ||
|
||
async findNoteByIdMongo(id: string) { | ||
return this.noteModel.findOne({ id }).exec(); | ||
} | ||
|
||
async createSpaceMongo(data: any) { | ||
const space = new this.spaceModel(data); | ||
return space.save(); | ||
} | ||
|
||
async createNoteMongo(data: any) { | ||
const note = new this.noteModel(data); | ||
return note.save(); | ||
} | ||
} |
Oops, something went wrong.