首页 文章

MySQL与MongoDB 1000读取

提问于
浏览
278

我对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 回答

  • 28

    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如何在某些用例中提高性能 .

  • 51

    你有并发性,即同时用户?如果你只是直接运行1000次查询,只有一个线程,几乎没有区别 . 这些引擎太容易了:)

    但我强烈建议您构建一个真正的负载测试会话,这意味着在同一时间使用JMeter等注入器与10,20或50个用户,这样您就可以真正看到差异(尝试将此代码嵌入到网页JMeter中)可以查询) .

    我今天刚刚在一台服务器(以及一个简单的集合/表)上完成了它,结果非常有趣且令人惊讶(与MyISAM引擎和InnoDb引擎相比,MongoDb在写入和读取方面确实更快) .

    这应该是你的测试的一部分:并发和MySQL引擎 . 然后,数据/架构设计和应用程序需求当然是超出响应时间的巨大要求 . 让我知道当你得到结果时,我也需要对此有所了解!

  • 17

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

    男人,,,答案是你基本上测试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 .

  • 10

    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

    ________________________________________________
    GOLANG with MySQL (engine = MyISAM)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                INSERT
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    10                      1.195444ms
    100                     6.075053ms
    1000                    47.439699ms
    10000                   483.999809ms
    100000                  4.707089053s
    1000000                 49.067407174s
    
    
                SELECT
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1000000                 872.709µs
    
    
            SELECT & DISPLAY
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1000000                 20.717354746s
    
    
                UPDATE
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1000000                 2.309209968s
    100000                  257.411502ms
    10000                   26.73954ms
    1000                    3.483926ms
    100                     915.17µs
    10                      650.166µs
    
    
                DELETE
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1000000                 6.065949ms
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    
    ________________________________________________
    GOLANG with MongoDB
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                INSERT
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    10                      2.067094ms
    100                     8.841597ms
    1000                    106.491732ms
    10000                   998.225023ms
    100000                  8.98172825s
    1000000                 1m 29.63203158s
    
    
                SELECT
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1000000                 5.251337439s
    
    
            FIND & DISPLAY (with index declared)
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1000000                 21.540603252s
    
    
                UPDATE
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1                       1.330954ms
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    ________________________________________________
    PHP5 with MySQL (engine = MyISAM)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                INSERT
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
     10                     0.0040680000000001s
     100                    0.011595s
     1000                   0.049718s
     10000                  0.457164s
     100000                 4s
     1000000                42s
    
    
                SELECT
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
     1000000                <1s
    
    
                SELECT & DISPLAY
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
      1000000               20s
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    ________________________________________________
    PHP5 with MongoDB 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                INSERT
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    10                      0.065744s
    100                     0.190966s
    1000                    0.2163s
    10000                   1s
    100000                  8s
    1000000                 78s
    
    
                FIND
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1000000                 <1s
    
    
                FIND & DISPLAY
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1000000                 7s
    
    
                UPDATE
    ------------------------------------------------
    num of rows             time taken
    ------------------------------------------------
    1000000                 9s
    
  • 4

    这是a little research使用MySQL和Mongo探索了RDBMS与NoSQL,结论与@Sean Reilly的回应一致 . 简而言之,好处来自设计,而不是原始的速度差异 . 第35-36页的结论:

    RDBMS vs NoSQL: Performance and Scaling Comparison

    该项目测试,分析并比较了两种数据库类型的性能和可伸缩性 . 完成的实验包括运行不同数量和类型的查询,其中一些比其他查询更复杂,以便分析数据库如何随着负载的增加而扩展 . 在这种情况下最重要的因素是用作MongoDB的查询类型可以更快地处理更复杂的查询,这主要是因为它牺牲了数据复制的简单模式,这意味着NoSQL数据库可能包含大量的数据重复 . 虽然可以使用直接从RDBMS迁移的模式,但这将消除MongoDB的子文档的基础数据表示的优势,这允许在组合表时对数据库使用较少的查询 . 尽管MongoDB在这些复杂的查询中对MySQL的性能提升,但当基准测试使用嵌套的SELECT时,MySQL查询类似于MongoDB复杂查询,MySQL表现最好,尽管在更高的连接数下,两者表现相似 . 基准测试的最后一种类型是包含两个JOINS和子查询的复杂查询,显示了MongoDB由于使用了子文档而优于MySQL的优势 . 这种优势是以数据复制为代价的,这导致数据库大小的增加 . 如果此类查询在应用程序中是典型的,那么考虑NoSQL数据库作为替代方案同时考虑由较大的数据库大小导致的存储和内存大小的成本是很重要的 .

  • 570

    在单个服务器上,MongoDb在读取和写入时不会比mysql MyISAM快,因为表/ doc大小小到1 GB到20 GB .
    MonoDB在多节点集群上的Parallel Reduce上会更快,而Mysql不能在水平上进行扩展 .

相关问题