为了账号安全,请及时绑定邮箱和手机立即绑定

MySQL vs MongoDB 1000读取

/ 猿问

MySQL vs MongoDB 1000读取

我对MongoDb感到非常兴奋,并且最近对其进行了测试。我在MySQL中有一个名为posts的表,其中大约2000万条记录仅在名为“ id”的字段上建立索引。


我想将速度与MongoDB进行比较,然后运行了一个测试,该测试将从我们的大型数据库中随机获取并打印15条记录。我为mysql和MongoDB分别运行了约1,000次查询,但我很惊讶我没有注意到速度上的很大差异。也许MongoDB快1.1倍。真令人失望。我做错什么了吗?我知道我的测试并不完美,但是在阅读繁琐的杂物方面,MySQL与MongoDb相当。



注意:


我有双核+(2个线程)i7 cpu和4GB ram

我在MySQL上有20个分区,每个分区有1百万条记录

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

}

?>


查看完整描述

3 回答

?
慕后森

MongoDB并不是神奇的更快。如果您以相同的方式存储相同的数据,并以完全相同的方式对其进行访问,那么您真的不应该期望结果会大相径庭。毕竟,MySQL和MongoDB都是GPL,因此,如果Mongo中包含一些神奇的更好的IO代码,则MySQL团队可以将其合并到他们的代码库中。

人们看到现实世界中的MongoDB性能主要是因为MongoDB允许您以更适合您的工作负载的不同方式查询。

例如,考虑一种设计,该设计以规范化方式保留了有关复杂实体的许多信息。这可以轻松地使用MySQL(或任何关系数据库)中的数十个表以标准形式存储数据,并需要许多索引来确保表之间的关系完整性。

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

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

  • 在集合上进行一次索引查找(假设通过id获取实体)

  • 检索一个数据库页面的内容(实际的二进制json文档)

因此,进行b树查找,并读取二进制页面。Log(n)+ 1个IO 如果索引可以完全驻留在内存中,则为1 IO。

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

  • 在根表上进行一次索引查找(同样,假设该实体是通过id获取的)

  • 对于聚集索引,我们可以假设根行的值在索引中

  • 实体pk值的20多次范围查找(希望在索引上)

  • 这些可能不是聚集索引,因此一旦我们确定了合适的子行是什么,就进行了20多个相同的数据查找。

因此,即使假设所有索引都在内存中(这比较困难,因为它们的数量是20倍),mysql的总数也大约为20个范围查找。

这些范围查找可能由随机IO组成-不同的表肯定会驻留在磁盘上的不同位置,并且同一实体在同一表的同一范围内的不同行可能不连续(取决于该实体的状态)更新等)。

因此,对于此示例,与MongoDB相比,每个逻辑访问的最终IO数比MySQL多20倍

这是MongoDB 在某些用例中可以提高性能的方式。


查看完整回答
反对 回复 2019-12-07
?
忽然笑

您是否有并发性,即同时使用用户?如果仅使用一个线程直接运行1000次查询,则几乎没有区别。这些引擎太简单了:)

但我强烈建议您建立一个真正的负载测试会话,这意味着在同一时间使用具有10、20或50个用户的注入器(例如JMeter),以便您能真正看到差异(尝试将此代码嵌入JMeter网页中可以查询)。

今天,我只是在一台服务器(和一个简单的集合/表)上完成此操作,结果非常有趣且令人惊讶(与MyISAM引擎和InnoDb引擎相比,MongoDb的读写速度确实更快)。

这确实应该是测试的一部分:并发和MySQL引擎。然后,数据/架构设计和应用程序需求当然是巨大的需求,而不是响应时间。让我知道您获得结果时,我也需要有关此的输入!


查看完整回答
反对 回复 2019-12-07
?
波斯汪

资料来源: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)


查看完整回答
反对 回复 2019-12-07

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信