我对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;
}
?>
答案 0 :(得分:597)
MongoDB的神奇速度并不快。如果您存储相同的数据,以基本相同的方式组织,并以完全相同的方式访问它,那么您真的不应该期望您的结果大不相同。毕竟,MySQL和MongoDB都是GPL,所以如果Mongo有一些神奇的更好的IO代码,那么MySQL团队可以将它合并到他们的代码库中。
人们看到真实世界的MongoDB性能很大程度上是因为MongoDB允许您以不同的方式查询,这对您的工作负载更为明智。
例如,考虑一种以规范化方式持久保存有关复杂实体的大量信息的设计。这可以很容易地使用MySQL(或任何关系数据库)中的几十个表来以正常形式存储数据,需要许多索引来确保表之间的关系完整性。
现在考虑与文档存储相同的设计。如果所有这些相关表都从属于主表(并且它们通常是),那么您可以对数据建模,使整个实体存储在单个文档中。在MongoDB中,您可以将其作为单个文档存储在单个集合中。这就是MongoDB开始实现卓越性能的地方。
在MongoDB中,要检索整个实体,您必须执行:
所以b-tree查找和二进制页面读取。 Log(n)+ 1个IO。如果索引完全驻留在内存中,则为1 IO。
在具有20个表的MySQL中,您必须执行:
所以mysql的总数,即使假设所有索引都在内存中(由于它们的数量多20倍,因此更难)是大约20个范围查找。
这些范围查找可能包含随机IO - 不同的表肯定会驻留在磁盘上的不同位置,并且实体的同一表中相同范围内的不同行可能不是连续的(取决于实体的更新方式等)。
因此,对于这个示例,与MongoDB相比,最终的计数大约是 20次每个逻辑访问使用MySQL的IO。
这就是MongoDB如何在某些用例中提升性能。
答案 1 :(得分:53)
你有并发性,即同时用户?如果你只是直接运行1000次查询,只有一个线程,几乎没有区别。这些引擎太容易了:))
但我强烈建议您构建一个真正的负载测试会话,这意味着在同一时间使用JMeter等注入器与10,20或50个用户,这样您就可以真正看到差异(尝试将此代码嵌入到网页JMeter可以查询)。
我今天刚刚在一台服务器(以及一个简单的集合/表)上完成了它,结果非常有趣且令人惊讶(与MyISAM引擎和InnoDb引擎相比,MongoDb在写入和读取方面确实更快。) p>
这应该是你的测试的一部分:并发&amp; MySQL引擎。 然后,数据/架构设计&amp;应用程序需求当然是超出响应时间的巨大需求。让我知道当你得到结果时,我也需要对此有所了解!
答案 2 :(得分:31)
来源: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)
答案 3 :(得分:19)
man ,,,答案是你基本上是在测试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;
}
然后是一个主要的差异b / w内爆和。
最后发生了什么。看起来每次创建一个连接,因此它测试连接时间加上查询时间。
$m = new Mongo();
vs
$db = new AQLDatabase();
因此,对于剥离爵士乐的基础查询,你的速度提高101%可能会快1000%。
urghhh。
答案 4 :(得分:14)
https://github.com/reoxey/benchmark
<强>基准强>
MySQL&amp;的速度比较GOLANG1.6中的MongoDB&amp; PHP5
用于基准测试的系统:DELL cpu i5第四代1.70Ghz * 4 ram 4GB GPU内存2GB
对INSERT,SELECT,UPDATE,DELETE执行不同行数的RDBMS与NoSQL的速度比较10,100,1000,10000,100000,1000000
用于执行的语言是:PHP5&amp;谷歌最快的语言GO 1.6
<?php
$start_date1 = '2016-05-06 00:00:00';
$start_date2 = '2016-01-06 00:00:00';
$result1 = is_date_range_exceeds_3_months($start_date1);
$result2 = is_date_range_exceeds_3_months($start_date2);
//lets say 'now' is '2016-06-06 00:00:00'
//Expected result of $result1 = false
//Expected result of $result2 = true
?>
答案 5 :(得分:4)
以下a little research使用MySQL与Mongo探讨了RDBMS与NoSQL,结论与@Sean Reilly的回应相符。简而言之,好处来自设计,而不是原始的速度差异。第35-36页的结论:
RDBMS与NoSQL:性能和扩展比较
该项目测试,分析和比较了性能和 两种数据库类型的可伸缩性。完成的实验包括 运行不同数量和类型的查询,比一些更复杂 其他人,为了分析数据库如何扩大规模 加载。在这种情况下,最重要的因素是使用的查询类型 因为MongoDB可以更快地处理更复杂的查询,主要是因为它 牺牲数据重复的简单模式意味着a NoSQL数据库可能包含大量数据重复。虽然 可以使用直接从RDBMS迁移的模式 消除了MongoDB底层数据表示的优势 子文档允许使用较少的查询 组合数据库作为表。 尽管性能提升了 当基准测试时,MongoDB在这些复杂的查询中超过了MySQL 类似于MongoDB复杂查询的MySQL查询建模 使用嵌套的SELECT尽管数字较高,但MySQL的表现最佳 两个连接的行为类似。 最后一种查询 基准测试,这是包含两个JOINS和a的复杂查询 子查询显示了MongoDB由于其使用而在MySQL上的优势 子文档。这种优势是以数据复制为代价的 这会导致数据库大小的增加。如果有这样的疑问 在应用程序中典型的是考虑NoSQL很重要 数据库作为替代方案 考虑到较大的存储和内存大小的成本 数据库大小。
答案 6 :(得分:-1)
老实说,即使MongoDB速度较慢,MongoDB绝对会让我和你的编码更快。...无需担心表列,行或实体的愚蠢迁移……
使用MongoDB,您只需实例化一个类并保存!
答案 7 :(得分:-6)
在单个服务器上,MongoDb在读取和写入时不会比mysql MyISAM快,给定表/ doc 尺寸小1 GB到20 GB MonoDB在Multi-Node集群上的Parallel Reduce上会更快,而Mysql无法在水平上进行扩展。