私はMongoDbに非常に興奮しており、最近それをテストしています。 MySQLにはpostsという名前のテーブルがあり、約2000万件のレコードが 'id'というフィールドにのみインデックス付けされています。
私はMongoDBとスピードを比較したいと思っていて、私たちの巨大なデータベースからランダムに15レコードを取得して印刷するテストを実行しました。私はmysqlとMongoDBに対してそれぞれ約1000回クエリを実行しましたが、速度の違いにそれほど気付かないことに驚きました。たぶんMongoDBは1.1倍速いです。それは非常に残念です。私が間違っていることはありますか?私のテストは完璧ではないことを知っていますが、集中的な雑用を読むことに関してはMySQLはMongoDbと同等です。
注意:
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(または任意のリレーショナルデータベース)の多数のテーブルを簡単に使用してデータを通常の形式で格納でき、テーブル間のリレーショナル整合性を確保するには多くのインデックスが必要です。
次に、ドキュメントストアを使用した同じ設計を検討します。これらのすべての関連テーブルがメインテーブルに従属している場合(多くの場合はそうです)、エンティティ全体が1つのドキュメントに格納されるようにデータをモデル化できる場合があります。 MongoDBでは、これを単一のドキュメントとして単一のコレクションに保存できます。これは、MongoDBが優れたパフォーマンスを可能にし始めるところです。
MongoDBでは、エンティティ全体を取得するには、次を実行する必要があります。
したがって、Bツリールックアップ、およびバイナリページの読み取り。 Log(n)+ 1 IO。インデックスが完全にメモリに常駐できる場合、1 IO。
20テーブルのMySQLでは、次を実行する必要があります。
したがって、mysqlの合計は、すべてのインデックスがメモリ内にあると仮定しても(それらの20倍の数があるのでより困難です)、約20の範囲ルックアップです。
これらの範囲ルックアップはランダムIOで構成されている可能性があります-異なるテーブルがディスク上の異なるスポットに必ず存在し、エンティティの同じテーブル内の同じ範囲内の異なる行が連続していない可能性がありますエンティティの更新方法など)。
したがって、この例では、最終的な集計は、MongoDBと比較して、MySQLでの論理アクセスごとに20回 more IOです。
これは、MongoDBがパフォーマンスを向上させる方法です一部のユースケース。
同時ユーザー、つまり同時ユーザーはいますか。たった1つのスレッドで1000倍のクエリを実行しただけでは、ほとんど違いはありません。これらのエンジンにとっては余りにも簡単:)
ただし、実際の負荷テストセッションを作成することを強くお勧めします。つまり、10、20、50ユーザーのJMeterなどのインジェクタを使用することです。[AT THE SAME TIME Webページ内のコードJMeterが問い合わせることができます)。
今日は1台のサーバー(および単純なコレクション/テーブル)でそれを実行しましたが、結果は非常に興味深く、驚くべきものです(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>";
}
もう一方のチャンクは、多数のRand番号をまとめるために費やしています。
function get_15_random_numbers()
{
$numbers = array();
for($i=1;$i<=15;$i++)
{
$numbers[] = mt_Rand(1, 20000000) ;
}
return $numbers;
}
それからb/w爆縮とで大きな違いがあります。
そして最後にここで何が起こっているのか。毎回接続を作成するように見えるので、接続時間とクエリ時間をテストします。
$m = new Mongo();
vs
$db = new AQLDatabase();
そのため、101%速いあなたのジャズの根本的なクエリの1000%速いことがわかるかもしれません。
うーん。
https://github.com/reoxey/benchmark
ベンチマーク
gOLANG1.6とPHP5でのMySQLとMongoDBのスピード比較
ベンチマークに使用されるシステム:Dell CPU i5第4世代1.70GHz * 4ラム4GB GPUラム2GB
INSERT、SELECT、UPDATE、DELETEでRDBMSとNoSQLを比較して異なる行数を実行した場合
実行に使用される言語は次のとおりです。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対Mongoを使用してRDBMS対NoSQLを調査した、結論は@ Sean Reillyの応答と一致していました。一言で言えば、利点は設計から来るのであり、生の速度差ではありません。 35-36ページの結論:
RDBMSとNoSQL:性能とスケーリングの比較
プロジェクトは、2つのデータベースタイプのパフォーマンスとスケーラビリティをテスト、分析、および比較しました。行われた実験では、データベースが負荷の増大に応じてどのように拡張されたかを分析するために、さまざまな数および種類のクエリを実行しました。この場合の最も重要な要素は、主にデータの重複を犠牲にした単純なスキーマのため、MongoDBがより複雑なクエリをより速く処理できるように使用されるクエリタイプです。 RDBMSから直接移行されたスキーマを使用することができますが、これはMongoDBのサブドキュメントの基礎となるデータ表現の利点を排除します。 これらの複雑なクエリでMongoDBがMySQLに比べてパフォーマンスが向上したにもかかわらず、ベンチマークがネストしたSELECTを使用してMongoDBの複雑なクエリと同様にMySQLクエリをモデル化したとき。 2つのJOINと1つのサブクエリを含む複雑なクエリである最後のベンチマークのクエリでは、サブドキュメントを使用しているためMongoDBがMySQLより優れていることがわかりました。この利点はデータの重複を犠牲にしてデータベースサイズの増加を引き起こします。そのようなクエリがアプリケーションで一般的である場合、より大きいデータベースサイズに起因するストレージおよびメモリサイズのコストを考慮しながら、NoSQLデータベースを代替手段と見なすことが重要です。