MySQL与MongoDB 1000读取

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

我想比较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;
    }
    ?>
    

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

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

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

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

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

  • 对集合进行一次索引查找(假设实体是通过id获取的)
  • 检索一个数据库页面的内容(实际的二进制json文档)
  • 所以一个B树查找,和一个二进制页面读取。 日志(n)+ 1个IO。 如果索引可以完全驻留在内存中,那么1个IO。

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

  • 在根表上进行一次索引查找(同样,假设实体由id获取)
  • 对于聚集索引,我们可以假定根行的值在索引中
  • 20+范围查找(希望在索引上)实体的pk值
  • 这些可能不是聚簇索引,因此,一旦我们找出适当的子行是什么,就会有相同的20+数据查找。
  • 因此,即使假定所有索引都在内存中(这比较困难,因为它们有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

    上一篇: MySQL vs MongoDB 1000 reads

    下一篇: How can I rename a field for all documents in MongoDB?