我对MongoDb非常兴奋并且最近一直在测试它 . 我在MySQL中有一个名为posts的表,大约有2000万条记录仅在名为“id”的字段上编入索引 .
我想比较速度与MongoDB,我运行了一个测试,可以从我们庞大的数据库中随机获取和打印15条记录 . 我为mysql和MongoDB运行了大约1000次查询,我很惊讶我没有注意到速度上的很多差异 . 也许MongoDB快了1.1倍 . 这非常令人失望 . 有什么我做错了吗?我知道我的测试并不完美,但是当涉及阅读密集的家务时,MySQL与MongoDb相当 .
注意:
-
我有双核(2线程)i7 cpu和4GB内存
-
我在MySQL上有20个分区,每个分区有100万条记录
Sample Code Used For Testing 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;
}
?>
Sample Code For Testing 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;
}
?>
7 回答
MongoDB并不神奇 . 如果您存储相同的数据,以基本相同的方式组织,并以完全相同的方式访问它,那么您真的不应该期望您的结果大不相同 . 毕竟,MySQL和MongoDB都是GPL,所以如果Mongo有一些神奇的更好的IO代码,那么MySQL团队可以将它合并到他们的代码库中 .
人们看到真实世界的MongoDB性能很大程度上是因为MongoDB允许您以不同的方式查询,这对您的工作负载更为明智 .
例如,考虑一种以规范化方式持久保存有关复杂实体的大量信息的设计 . 这可以很容易地使用MySQL(或任何关系数据库)中的几十个表来以正常形式存储数据,需要许多索引来确保表之间的关系完整性 .
现在考虑与文档存储相同的设计 . 如果所有这些相关表都从属于主表(并且它们通常是),那么您可以对数据建模,使整个实体存储在单个文档中 . 在MongoDB中,您可以将其作为单个文档存储在单个集合中 . 这是MongoDB开始实现卓越性能的地方 .
在MongoDB中,要检索整个实体,您必须执行:
对集合进行一次索引查找(假设实体是由id获取的)
检索一个数据库页面的内容(实际的二进制json文档)
所以b-tree查找和二进制页面读取 . 记录(n)1个IO . 如果索引可以完全驻留在内存中,那么1 IO .
在具有20个表的MySQL中,您必须执行:
根表上的一个索引查找(再次假设实体是由id获取的)
使用聚簇索引,我们可以假设根行的值在索引中
20个范围查找(希望在索引上)实体的pk值
这些可能不是聚簇索引,因此一旦我们弄清楚相应的子行是什么,就要进行相同的20次数据查找 .
所以mysql的总数,即使假设所有索引都在内存中(由于它们的数量多20倍,因此更难)是大约20个范围查找 .
这些范围查找可能包含随机IO - 不同的表肯定会驻留在磁盘上的不同位置,并且实体的同一表中相同范围内的不同行可能不是连续的(取决于实体的实现方式)更新等) .
因此,对于此示例,与MongoDB相比,每个逻辑访问的最终计数大约是MySQL的20倍 .
这就是MongoDB如何在某些用例中提高性能 .
你有并发性,即同时用户?如果你只是直接运行1000次查询,只有一个线程,几乎没有区别 . 这些引擎太容易了:)
但我强烈建议您构建一个真正的负载测试会话,这意味着在同一时间使用JMeter等注入器与10,20或50个用户,这样您就可以真正看到差异(尝试将此代码嵌入到网页JMeter中)可以查询) .
我今天刚刚在一台服务器(以及一个简单的集合/表)上完成了它,结果非常有趣且令人惊讶(与MyISAM引擎和InnoDb引擎相比,MongoDb在写入和读取方面确实更快) .
这应该是你的测试的一部分:并发和MySQL引擎 . 然后,数据/架构设计和应用程序需求当然是超出响应时间的巨大要求 . 让我知道当你得到结果时,我也需要对此有所了解!
资料来源:https://github.com/webcaetano/mongo-mysql
10行
100行
1000行
10.000行
男人,,,答案是你基本上测试PHP而不是数据库 .
无论是否注释掉印刷品,都不要费心去迭代结果 . 有一大块时间 .
而另一块人正在花费大量的兰特数字 .
然后是一个主要的差异b / w内爆和进入 .
最后这里发生了什么 . 看起来每次都创建一个连接,因此它测试连接时间加上查询时间 .
VS
所以对于剥离爵士乐的基础查询,你的速度提高101%可能会快1000% .
urghhh .
https://github.com/reoxey/benchmark
benchmark
GOLANG1.6和PHP5中MySQL和MongoDB的速度比较
系统用于基准:DELL cpu i5第四代1.70Ghz * 4 ram 4GB GPU ram 2GB
对于INSERT,SELECT,UPDATE,DELETE执行不同行数的RDBMS与NoSQL的速度比较10,100,1000,10000,100000,1000000
用于执行的语言是:PHP5和Google最快的语言GO 1.6
这是a little research使用MySQL和Mongo探索了RDBMS与NoSQL,结论与@Sean Reilly的回应一致 . 简而言之,好处来自设计,而不是原始的速度差异 . 第35-36页的结论:
RDBMS vs NoSQL: Performance and Scaling Comparison
在单个服务器上,MongoDb在读取和写入时不会比mysql MyISAM快,因为表/ doc大小小到1 GB到20 GB .
MonoDB在多节点集群上的Parallel Reduce上会更快,而Mysql不能在水平上进行扩展 .