# MySQL vs MongoDB 성능 분석

## 개요

프로젝트를 수행하기에 앞서, 적절한 DBMS를 선정하기 위해 2개의 상용 데이터베이스의 성능을 비교하기 위해 지정된 시나리오에 따라 테스트를 진행하였다.

## 테스트 환경

| 구분       | 내용                           |
| -------- | ---------------------------- |
| OS       | MacOS Mojabe 10.14.5         |
| MySQL    | 5.7.26                       |
| MongoDB  | 4.0.3                        |
| CPU      | INTEL I5 7267U 7th Kaby Lake |
| RAM      | 8GB                          |
| Data Set | 나무위키 데이터베이스 덤프(약 7GB)        |

## 데이터 셋 출처

[나무위키:데이터베이스 덤프](https://namu.wiki/w/%EB%82%98%EB%AC%B4%EC%9C%84%ED%82%A4:%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%20%EB%8D%A4%ED%94%84)

{% embed url="<https://bit.ly/2P4YoEu>" %}

## 데이터 셋 삽입

테스트에 들어가기 앞서, 나무 위키 데이터는 JSON형식의 데이터 셋을  MongoDB에 먼저 덤프를 씌어준 후, 그대로 MySQL에 같은 데이터를 삽입한다.

INT 탐색 테스트를 수행하기 위해 추가로 1 \~ 10만 사이의 랜덤 숫자 25만 개를 넣어주었다.

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2d1XJs_dBEVVOjH5l%2Fimage.png?alt=media\&token=e7b742a0-ea94-41ff-86bb-06fd6d8cc42f)

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2d2k8E16yi8HyFld9%2Fimage.png?alt=media\&token=675776c6-b858-44b4-8221-69f818e24c70)

## INT 성능 비교

MySQL, MongoDB 둘 다 검색할 랜덤 숫자 1000개는 동일하다.앞으로 이 숫자를 기반으로 25만 개의 데이터를 검색해보았다.  랜덤 숫자는 약 10만 개 정도로 평균적으로 2,3 개 정도의 중복을 포함하고 있다.

### MySQL - No Index

#### 실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2f9FAwWrFzoeqwyeK%2Fimage.png?alt=media\&token=d69a815f-78a7-4f73-884e-3efc6859df9b)

#### 분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2fEmgCIB_kF56KW6c%2Fimage.png?alt=media\&token=dcad7a7c-9e56-4b02-9af7-75431b791140)

### MongoDB - No Index

#### 실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2fVVMMS8V4OCZf7O5%2Fimage.png?alt=media\&token=bb50d4fd-9845-41e5-8c65-3d0d82870271)

#### 분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2fYQyVR_FBdBN5_rA%2Fimage.png?alt=media\&token=c079b9d2-83da-42ff-82ec-6187ac333ef4)

### MySQL - Index

#### &#x20;실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2gcfFZxkt37r3zG1f%2Fimage.png?alt=media\&token=c98e6d06-664b-4c17-bc67-3f6037d4dd41)

#### 분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2gtYOrnUjdFCcu8eF%2Fimage.png?alt=media\&token=e6eb8e16-334c-47c3-9714-45ffde83e762)

### MongoDB - Index&#x20;

#### 실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2hDg2iCOSkuFr_hLS%2Fimage.png?alt=media\&token=bb83237b-7708-4f10-a251-83046e5ab3c2)

#### 분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2hFdzjDvbxW7MJ1oE%2Fimage.png?alt=media\&token=148aa601-c424-4ea7-a73a-4678ed4bedf4)

### 분석 결과

| DB      | No Index 측정 시간 | Index 측정 시간 | 성능 개선 비율  |
| ------- | -------------- | ----------- | --------- |
| MySQL   | 418 sec        | 0.3123 sec  | 약 1,393 배 |
| MongoDB | 3117 sec       | 1.0126 sec  | 약 3,078 배 |

Index에 무관하게 MySQL이 일관되게 우수한 성능을 보여주었다.

## STRING 동치 비교 분석

&#x20;문자열 데이터의 경우, 각각의 DB에서 동치 연산 및 부분 문자열 연산이 존재하기 때문에 모두 테스트를 수행하였다. 동치 비교 분석은 해당 문자열에 대하여 Equal(==) 연산으로 탐색을 수행한 테스트이다.

### MySQL - No Index

#### 실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2jhq3xiqL6bOFJOnm%2Fimage.png?alt=media\&token=59faf41d-38ad-485c-9b46-58596d8ea06a)

#### &#x20;분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2jtUpYBPBpPJyqgWj%2Fimage.png?alt=media\&token=a1d9dbe8-466f-404d-9d62-c109c2373b23)

### MongoDB - No Index

#### 실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2kUckG8pjYg2Cx-qd%2Fimage.png?alt=media\&token=3bc3f841-d99c-40e9-a873-35b166d37df7)

#### 분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2kWcvbJg8DldqUD1Z%2Fimage.png?alt=media\&token=3667ab39-9958-4114-bd2a-1af12937f03a)

### MySQL - Index

#### 분석 결과&#x20;

MySQL의 경우, Text Index를 적용시킬 때 인덱싱시킬 텍스트 값 길이를 반드시 명시해주어야 하기 때문에 해당 길이를 최대 700으로 제한하였다.

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2khWe9e2hYq9UoRgZ%2Fimage.png?alt=media\&token=0074161b-abaa-4b23-863d-86490d2ed925)

### MongoDB - Index

#### 분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-Ln2bAk_E5e_Y3VEzpUv%2F-Ln2kiybgmQgrf9m6-ft%2Fimage.png?alt=media\&token=1d60d8ee-ca5c-43d9-945e-d54041420bb0)

### 분석 결과

| DB      | No Index 측정 시간 | Index 측정 시간 | 성능 개선 비율 |
| ------- | -------------- | ----------- | -------- |
| MySQL   | 18.1485 sec    | 0.0028 sec  | 약 9,000배 |
| MongoDB | 11.7807 sec    | 7.7963 sec  | 약 1.5배   |

MySQL이 압도적인 성능을 나타내는 것으로 보이나, MySQL은 최대 인덱스 길이를 700자 정도로 제한하였기 때문에,  전문에 인덱스를 적용시킨 유의미한 평가 지표라 판단하기 힘들다. 즉,  유효한 분석 결과는 No Index 측정 시간 뿐이다.

## STRING 부분 연산

부분 연산을 수행하기 위해 각각의 데이터베이스에 Full Text Index를 적용시킨 후, 한글 및 영어에 빈도수가 다양하게 존재하는 단어 50개를 선정하였다.

부분 문자열 탐색을 수행하기 위하여, 다음과 같은 데이터 셋을 사용하였다.

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbWlf4wWBK-4-UUmic%2Fimage.png?alt=media\&token=2e01d830-1b99-42cb-affd-941f355f7886)

### MySQL - No Index

#### 실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbWolTpctUe4Lk1r24%2Fimage.png?alt=media\&token=c1c1499f-fd71-4353-8bd3-1fffbd43d034)

#### 분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbWq7hlDNCgJSL0df7%2Fimage.png?alt=media\&token=af2d2b10-963f-4faf-ae32-f39f272cf0c8)

### MongoDB - No Index

#### 실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbWyvWwIo9ImqDe_e2%2Fimage.png?alt=media\&token=ef4dc0a5-5229-4f88-85c5-65249041bc43)

#### 분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbWzhJrLA3ZMLGRAc6%2Fimage.png?alt=media\&token=477c245c-d9b2-4269-af75-4246d66db490)

### MySQL - Index

#### 실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbX2ABDESncn-f93H0%2Fimage.png?alt=media\&token=d554b2d1-f4e7-40e0-941b-3837a5251916)

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbWscO-aCvxMCMh8Yn%2Fimage.png?alt=media\&token=bb99f485-402c-443d-b027-19ff52ba4dc3)

#### &#x20;분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbWxcNw18t5Cnlc3_w%2Fimage.png?alt=media\&token=ed07f3fb-994b-46e2-a6f2-51f7944f3f13)

### MongoDB - Index

#### &#x20;실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbX66P58KNXRZbxGiv%2Fimage.png?alt=media\&token=23ac25b6-1120-45fe-8f07-4b21aab3b16c)

#### &#x20;분석 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbX6zG0kJajQsAVJdp%2Fimage.png?alt=media\&token=6a79a49e-9e01-41cd-8798-1f38d3c69e8d)

### 분석 결과

| DB      | <p>No Index <br>측정 시간 </p> | <p>Index <br>측정 시간</p> | 성능 개선 비율 | 단어 소실 |
| ------- | -------------------------- | ---------------------- | -------- | ----- |
| MySQL   | 1347sec                    | 75sec                  | 17.96배   | 발생    |
| MongoDB | 947sec                     | 24sec                  | 39.45배   | 발생    |

&#x20;MongoDB가 MySQL에 비해 전반적으로 우수한 성능을 보여주었다. 그러나 양쪽 다 Full Tabel Scan에 비해 많은 양의 단어가 소실되었으며, 상대적으로 MongoDB에서 더 많은 소실량을 확인할 수 있다.

## Array/Join 탐색

MongoDB의 Array 내의 연산 및 MySQL의 JOIN 연산의 성능을 비교한다. 해당 테스트의 경우 인덱스를 사용하지 않는다. 동일한 조건에 테스트를 수행하기 위해 아래와 같은 구문을 각 DBMS에서 수행하도록 한다.

#### &#x20;"ㅁㅁㅁ"의 단어를 포함하면서(AND), "XXX" 혹은(OR) "XXXX"가 수정한 포스트를 찾아라

### MySQL(JOIN)

&#x20;post 테이블과 post\_contributors의 테이블을 JOIN연산을 수행하였다.

실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbYyp-94I2oJW4Goxu%2Fimage.png?alt=media\&token=4727704b-b4e4-4f5c-a96c-dfbca6ac86df)

실행 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbZ-iGdEKliLeLxrje%2Fimage.png?alt=media\&token=4679d4d2-bb71-45d1-8849-fffec44c7527)

### MongoDB(Array)

MongoDB의 경우, Array 자료형으로 각 document마다 내장된 contributors 칼럼에 대하여 연산을 수행하였다.

#### 실행 코드

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbZDSPxv98cCz0opoj%2Fimage.png?alt=media\&token=714d5136-c288-47d2-8ec9-66abb22f3b60)

#### 실행 결과

![](https://728901758-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L_Wo7SRUvbKJuPojzzZ%2F-LnbW_dYufS9XEhRR8eI%2F-LnbZFgpVKejErTXoOV8%2Fimage.png?alt=media\&token=0d50d45c-e6f1-40dd-a9de-e4121612a16e)

### 분석 결과

| DB      | <p><br>측정 시간 </p> |
| ------- | ----------------- |
| MySQL   | 9239sec           |
| MongoDB | 1670sec           |

&#x20;MongoDB가 압도적인 성능을  보여주었다. 예전부터 존재했던 MySQL 내의 JOIN 성능 이슈를 감안하면 타당한 결과라고 생각된다.

## 결과 해석

여러가지 테스트 상황을  상정하여 고려해보았을 때, SOOJLE 서비스의 DBMS는 NoSQL - MongoDB로 채택하는 것이 이상적인 것으로 판단된다.&#x20;
