MySQL vs MongoDB 1000读取

时间:2012-03-14 13:09:44

标签: mysql performance mongodb

我对MongoDb非常兴奋并且最近一直在测试它。我在MySQL中有一个名为posts的表,大约有2000万条记录仅在名为“id”的字段上编入索引。

我想比较MongoDB的速度,我运行了一个测试,可以从我们庞大的数据库中随机获取和打印15条记录。我为mysql和MongoDB运行了大约1000次查询,我很惊讶我没有注意到速度上的很多差异。也许MongoDB快了1.1倍。这非常令人失望。有什么我做错了吗?我知道我的测试并不完美,但是当涉及阅读密集的家务时,MySQL与MongoDb相当。


注意:

  • 我有双核+(2线程)i7 cpu和4GB ram
  • 我在MySQL上有20个分区,每个分区有100万条记录

用于测试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;
}
?>

8 个答案:

答案 0 :(得分:597)

MongoDB的神奇速度并不快。如果您存储相同的数据,以基本相同的方式组织,并以完全相同的方式访问它,那么您真的不应该期望您的结果大不相同。毕竟,MySQL和MongoDB都是GPL,所以如果Mongo有一些神奇的更好的IO代码,那么MySQL团队可以将它合并到他们的代码库中。

人们看到真实世界的MongoDB性能很大程度上是因为MongoDB允许您以不同的方式查询,这对您的工作负载更为明智。

例如,考虑一种以规范化方式持久保存有关复杂实体的大量信息的设计。这可以很容易地使用MySQL(或任何关系数据库)中的几十个表来以正常形式存储数据,需要许多索引来确保表之间的关系完整性。

现在考虑与文档存储相同的设计。如果所有这些相关表都从属于主表(并且它们通常是),那么您可以对数据建模,使整个实体存储在单个文档中。在MongoDB中,您可以将其作为单个文档存储在单个集合中。这就是MongoDB开始实现卓越性能的地方。

在MongoDB中,要检索整个实体,您必须执行:

  • 对集合进行一次索引查找(假设实体是由id获取的)
  • 检索一个数据库页面的内容(实际的二进制json文档)

所以b-tree查找和二进制页面读取。 Log(n)+ 1个IO。如果索引完全驻留在内存中,则为1 IO。

在具有20个表的MySQL中,您必须执行:

  • 在根表上进行一次索引查询(同样,假设实体是由id获取的)
  • 使用聚簇索引,我们可以假设根行的值在索引
  • 实体的pk值的20多个范围查找(希望在索引上)
  • 这些可能不是聚簇索引,因此一旦我们弄清楚适当的子行是什么,那么相同的20多个数据查找。

所以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速度较慢,Mon​​goDB绝对会让我和你的编码更快。...无需担心表列,行或实体的愚蠢迁移……

使用MongoDB,您只需实例化一个类并保存!

答案 7 :(得分:-6)

在单个服务器上,MongoDb在读取和写入时不会比mysql MyISAM快,给定表/ doc 尺寸小1 GB到20 GB MonoDB在Multi-Node集群上的Parallel Reduce上会更快,而Mysql无法在水平上进行扩展。