MySQL与MongoDB 1000读取
我对MongoDb感到非常兴奋,并且最近一直在进行测试。 我在MySQL中有一个名为posts的表,其中只有在名为'id'的字段上索引了大约2000万条记录。
我想比较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(或任何关系数据库)中的数十个表以常规形式存储数据,并且需要许多索引来确保表之间的关系完整性。
现在考虑与文档存储相同的设计。 如果所有这些相关表都从属于主表(并且通常是),那么您可能可以对数据建模,以使整个实体存储在单个文档中。 在MongoDB中,您可以将其作为单个文档存储在一个集合中。 这是MongoDB开始实现卓越性能的地方。
在MongoDB中,为了检索整个实体,您必须执行:
所以一个B树查找,和一个二进制页面读取。 日志(n)+ 1个IO。 如果索引可以完全驻留在内存中,那么1个IO。
在具有20个表的MySQL中,您必须执行:
因此,即使假定所有索引都在内存中(这比较困难,因为它们有20倍以上),所以mysql的总数大约是20个范围查找。
这些范围查找可能由随机IO组成 - 不同的表格肯定会驻留在磁盘上的不同位置,并且实体的同一表中相同范围内的不同行可能不是连续的(取决于实体的方式更新等)。
因此,对于这个示例,与MongoDB相比,每个逻辑访问的最终计数是使用MySQL的IO的约20倍。
这就是MongoDB在某些用例中可以提高性能的方式。
你有并发,即同时用户吗? 如果你只用一条线程直接运行1000次查询,则几乎没有区别。 这些引擎太容易了:)
但我强烈建议你建立一个真正的负载测试会话,这意味着在同一时间使用像JMeter这样的具有10,20或50个用户的注入器,这样你就可以真正看到不同之处(尝试在网页中嵌入这个代码JMeter可以查询)。
我今天在一台服务器(和一个简单的集合/表)上做了它,结果非常有趣和令人惊讶(与MyISAM引擎和InnoDb引擎相比,MongoDb在写入和读取方面确实更快)。
这真的应该成为你的测试的一部分:并发和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)
链接地址: http://www.djcxy.com/p/88747.html