MongoDb에 대해 매우 기대하고 있으며 최근에 테스트하고 있습니다. 나는 ‘id’라는 필드에서만 인덱스 된 약 2 천만 개의 레코드를 가진 MySQL에서 게시물이라는 테이블을 가지고있었습니다.
MongoDB와 속도를 비교하고 싶었고 거대한 데이터베이스에서 임의로 15 개의 레코드를 가져 와서 인쇄하는 테스트를 실행했습니다. 나는 mysql과 MongoDB에 대해 각각 약 1,000 번 쿼리를 실행했으며 속도에 큰 차이가 없다는 것을 놀라게했다. 아마도 MongoDB가 1.1 배 빠릅니다. 매우 실망 스럽습니다. 내가 잘못하고있는 것이 있습니까? 내 테스트가 완벽하지는 않지만 집중적 인 집안일을 읽을 때 MongoDb와 동등한 MySQL이라는 것을 알고 있습니다.
노트 :
- 듀얼 코어 + (2 스레드) i7 CPU 및 4GB 램이 있습니다
- MySQL에는 각각 1 백만 개의 레코드가 20 개 있습니다.
MongoDB 테스트에 사용되는 샘플 코드
<?php
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$time_taken = 0;
$tries = 100;
// connect
$time_start = microtime_float();
for($i=1;$i<=$tries;$i++)
{
$m = new Mongo();
$db = $m->swalif;
$cursor = $db->posts->find(array('id' => array('$in' => get_15_random_numbers())));
foreach ($cursor as $obj)
{
//echo $obj["thread_title"] . "<br><Br>";
}
}
$time_end = microtime_float();
$time_taken = $time_taken + ($time_end - $time_start);
echo $time_taken;
function get_15_random_numbers()
{
$numbers = array();
for($i=1;$i<=15;$i++)
{
$numbers[] = mt_rand(1, 20000000) ;
}
return $numbers;
}
?>
MySQL 테스트를위한 샘플 코드
<?php
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$BASE_PATH = "../src/";
include_once($BASE_PATH . "classes/forumdb.php");
$time_taken = 0;
$tries = 100;
$time_start = microtime_float();
for($i=1;$i<=$tries;$i++)
{
$db = new AQLDatabase();
$sql = "select * from posts_really_big where id in (".implode(',',get_15_random_numbers()).")";
$result = $db->executeSQL($sql);
while ($row = mysql_fetch_array($result) )
{
//echo $row["thread_title"] . "<br><Br>";
}
}
$time_end = microtime_float();
$time_taken = $time_taken + ($time_end - $time_start);
echo $time_taken;
function get_15_random_numbers()
{
$numbers = array();
for($i=1;$i<=15;$i++)
{
$numbers[] = mt_rand(1, 20000000);
}
return $numbers;
}
?>
답변
MongoDB는 마술처럼 빠르지 않습니다. 동일한 데이터를 저장하고 기본적으로 동일한 방식으로 구성하고 정확히 동일한 방식으로 액세스하면 결과가 크게 다를 것으로 기 대해서는 안됩니다. 결국 MySQL과 MongoDB는 모두 GPL이므로 Mongo에 마술로 더 나은 IO 코드가 있으면 MySQL 팀이 코드베이스에 통합 할 수 있습니다.
MongoDB를 사용하면 워크로드에 더 적합한 다른 방식으로 쿼리 할 수 있기 때문에 사람들은 실제 MongoDB 성능을 크게보고 있습니다.
예를 들어, 복잡한 엔티티에 대한 많은 정보를 정규화 된 방식으로 유지하는 설계를 생각해보십시오. 이를 통해 MySQL (또는 관계형 DB)에서 수십 개의 테이블을 쉽게 사용하여 데이터를 일반 형식으로 저장할 수 있으며 테이블 간의 관계 무결성을 보장하기 위해 많은 인덱스가 필요합니다.
이제 문서 저장소와 동일한 디자인을 고려하십시오. 이러한 관련 테이블이 모두 기본 테이블에 종속되는 경우 (종종 경우) 전체 엔터티가 단일 문서에 저장되도록 데이터를 모델링 할 수 있습니다. MongoDB에서는이를 단일 문서의 단일 컬렉션으로 저장할 수 있습니다. MongoDB가 탁월한 성능을 발휘하기 시작합니다.
MongoDB에서 전체 엔티티를 검색하려면 다음을 수행해야합니다.
- 컬렉션에서 하나의 인덱스 조회 (엔터티가 id로 페치되었다고 가정)
- 하나의 데이터베이스 페이지 (실제 이진 json 문서)의 내용을 검색합니다.
따라서 b- 트리 조회 및 이진 페이지를 읽습니다. Log (n) + 1 IO. 인덱스가 완전히 메모리에 상주 할 수 있으면 1 IO입니다.
20 개의 테이블이있는 MySQL에서는 다음을 수행해야합니다.
- 루트 테이블에서 하나의 인덱스 조회 (다시 엔티티가 id로 페치되었다고 가정)
- 클러스터형 인덱스를 사용하면 루트 행의 값이 인덱스에 있다고 가정 할 수 있습니다
- 엔터티의 pk 값에 대한 20 개 이상의 범위 조회 (희망 색인)
- 이들은 아마도 클러스터형 인덱스가 아니므로 적절한 하위 행이 무엇인지 파악하면 동일한 20 개 이상의 데이터 조회가 가능합니다.
따라서 모든 인덱스가 메모리에 있다고 가정하더라도 (모든 인덱스가 20 배 더 많기 때문에 더 어렵다) 가정하면 mysql의 총 범위는 약 20 범위입니다.
이러한 범위 조회는 임의 IO로 구성 될 가능성이 있습니다. 서로 다른 테이블이 디스크의 다른 지점에 확실히 상주 할 수 있으며, 엔티티에 대해 동일한 테이블에서 동일한 범위의 동일한 범위에있는 다른 행이 연속적이지 않을 수 있습니다 (엔티티가 어떻게 수행되었는지에 따라 다름) 업데이트 등).
따라서이 예의 경우 마지막 집계는 MongoDB에 비해 논리적 액세스 당 MySQL의 IO 가 약 20 배 더 높습니다.
이것은 MongoDB가 일부 사용 사례에서 성능 을 향상시키는 방법 입니다.
답변
동시성, 즉 동시 사용자가 있습니까? 하나의 스레드로 쿼리를 1000 배만 실행하면 거의 차이가 없습니다. 이 엔진에는 너무 쉽다 🙂
그러나 진정한로드 테스트 세션을 구축 할 것을 강력히 권장합니다. 즉, 같은 시간에 10, 20 또는 50 명의 사용자가있는 JMeter와 같은 인젝터를 사용하면 실제로 차이를 볼 수 있습니다 (이 코드를 웹 페이지 JMeter에 포함하려고 시도하십시오) 쿼리 가능).
방금 단일 서버 (및 간단한 컬렉션 / 테이블)에서 방금 수행했으며 결과는 매우 흥미롭고 놀랍습니다 (MongoDb는 MyISAM 엔진 및 InnoDb 엔진과 비교하여 쓰기 및 읽기에서 실제로 더 빠릅니다).
이것은 실제로 테스트의 일부 여야합니다 : 동시성 및 MySQL 엔진. 따라서 데이터 / 스키마 설계 및 애플리케이션 요구는 물론 응답 시간을 넘어서는 큰 요구 사항입니다. 결과를 얻으면 알려주십시오. 이에 대한 정보도 필요합니다!
답변
출처 : https://github.com/webcaetano/mongo-mysql
10 행
mysql insert: 1702ms
mysql select: 11ms
mongo insert: 47ms
mongo select: 12ms
100 행
mysql insert: 8171ms
mysql select: 10ms
mongo insert: 167ms
mongo select: 60ms
1000 행
mysql insert: 94813ms (1.58 minutes)
mysql select: 13ms
mongo insert: 1013ms
mongo select: 677ms
10.000 행
mysql insert: 924695ms (15.41 minutes)
mysql select: 144ms
mongo insert: 9956ms (9.95 seconds)
mongo select: 4539ms (4.539 seconds)
답변
대답은 기본적으로 데이터베이스가 아니라 PHP를 테스트한다는 것입니다.
인쇄 주석 처리 여부에 관계없이 결과를 반복하지 마십시오. 많은 시간이 있습니다.
foreach ($cursor as $obj)
{
//echo $obj["thread_title"] . "<br><Br>";
}
다른 청크는 많은 수의 랜드 숫자를 입력하는 데 소비됩니다.
function get_15_random_numbers()
{
$numbers = array();
for($i=1;$i<=15;$i++)
{
$numbers[] = mt_rand(1, 20000000) ;
}
return $numbers;
}
그다음에 큰 차이가 있습니다.
그리고 마지막으로 여기에서 무슨 일이 일어나고 있는지. 매번 연결을 만드는 것처럼 보이므로 연결 시간과 쿼리 시간을 테스트합니다.
$m = new Mongo();
vs
$db = new AQLDatabase();
따라서 재즈에서 제거 된 기본 쿼리에 대해 101 % 더 빠를 수 있습니다.
어 g.
답변
https://github.com/reoxey/benchmark
기준
GOLANG1.6 및 PHP5에서 MySQL 및 MongoDB의 속도 비교
벤치 마크에 사용되는 시스템 : DELL cpu i5 4 세대 1.70Ghz * 4ram 4GB GPU ram 2GB
다른 수의 행을 실행하는 INSERT, SELECT, UPDATE, DELETE에 대한 RDBMS와 NoSQL의 속도 비교 10,100,1000,10000,100000,1000000
실행에 사용되는 언어는 다음과 같습니다. PHP5 및 Google의 가장 빠른 언어 GO 1.6
________________________________________________
GOLANG with MySQL (engine = MyISAM)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INSERT
------------------------------------------------
num of rows time taken
------------------------------------------------
10 1.195444ms
100 6.075053ms
1000 47.439699ms
10000 483.999809ms
100000 4.707089053s
1000000 49.067407174s
SELECT
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 872.709µs
SELECT & DISPLAY
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 20.717354746s
UPDATE
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 2.309209968s
100000 257.411502ms
10000 26.73954ms
1000 3.483926ms
100 915.17µs
10 650.166µs
DELETE
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 6.065949ms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
________________________________________________
GOLANG with MongoDB
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INSERT
------------------------------------------------
num of rows time taken
------------------------------------------------
10 2.067094ms
100 8.841597ms
1000 106.491732ms
10000 998.225023ms
100000 8.98172825s
1000000 1m 29.63203158s
SELECT
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 5.251337439s
FIND & DISPLAY (with index declared)
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 21.540603252s
UPDATE
------------------------------------------------
num of rows time taken
------------------------------------------------
1 1.330954ms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
________________________________________________
PHP5 with MySQL (engine = MyISAM)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INSERT
------------------------------------------------
num of rows time taken
------------------------------------------------
10 0.0040680000000001s
100 0.011595s
1000 0.049718s
10000 0.457164s
100000 4s
1000000 42s
SELECT
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 <1s
SELECT & DISPLAY
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 20s
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
________________________________________________
PHP5 with MongoDB
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INSERT
------------------------------------------------
num of rows time taken
------------------------------------------------
10 0.065744s
100 0.190966s
1000 0.2163s
10000 1s
100000 8s
1000000 78s
FIND
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 <1s
FIND & DISPLAY
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 7s
UPDATE
------------------------------------------------
num of rows time taken
------------------------------------------------
1000000 9s
답변
다음은 MySQL vs Mongo를 사용하여 RDBMS vs NoSQL을 탐구 한 작은 연구 입니다. 결론은 @Sean Reilly의 답변과 일치합니다. 요컨대, 속도 차이가 아닌 디자인에서 이점을 얻을 수 있습니다. 35-36 페이지의 결론 :
RDBMS 및 NoSQL : 성능 및 스케일링 비교
이 프로젝트는 두 데이터베이스 유형의 성능과 확장 성을 테스트, 분석 및 비교했습니다. 수행 된 실험에는로드가 증가함에 따라 데이터베이스가 어떻게 확장되는지 분석하기 위해 다른 수와 유형의 쿼리를 실행하는 것이 포함되었습니다. 이 경우 가장 중요한 요소는 MongoDB가 사용하는 쿼리 유형이 주로 데이터 복제를 희생하여 단순한 스키마로 인해 더 복잡한 쿼리를 더 빠르게 처리 할 수 있다는 것입니다. 이는 NoSQL 데이터베이스에 많은 양의 데이터 복제본이 포함될 수 있음을 의미합니다. RDBMS에서 직접 마이그레이션 된 스키마를 사용할 수 있지만, 이는 테이블이 결합 될 때 데이터베이스에 대한 적은 쿼리를 사용할 수있게하는 하위 문서의 MongoDB 기본 데이터 표현의 이점을 제거합니다.이러한 복잡한 쿼리에서 MongoDB가 MySQL보다 성능을 향상 시켰음에도 불구하고 벤치 마크에서 중첩 된 SELECT를 사용하여 MongoDB 복잡한 쿼리와 유사하게 MySQL 쿼리를 모델링 할 때 연결 수가 많을수록 두 개가 비슷하게 동작했지만 MySQL이 가장 잘 수행되었습니다. 두 개의 JOINS와 하위 쿼리를 포함하는 복잡한 쿼리 인 벤치마킹 한 마지막 쿼리 유형은 하위 문서 사용으로 인해 MongoDB가 MySQL보다 유리하다는 점을 보여주었습니다. 이 장점은 데이터 중복 비용으로 인해 데이터베이스 크기가 증가합니다. 이러한 쿼리가 응용 프로그램에서 일반적인 경우 더 큰 데이터베이스 크기로 인한 스토리지 및 메모리 크기 비용을 고려하면서 NoSQL 데이터베이스를 대안으로 고려해야합니다.
답변
단일 서버에서 MongoDb는 테이블 및 문서 크기가 1GB에서 20GB로 작기 때문에 읽기 및 쓰기 모두에서 mysql MyISAM보다 빠르지 않습니다.
MyDB는 수평 확장이 불가능한 다중 노드 클러스터의 Parallel Reduce에서 MonoDB가 더 빠릅니다.