ChatGPT解决这个技术问题 Extra ChatGPT

MySQL 与 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 个分区,每个分区有 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;
}
?>
我不是 DBA,所以这是评论而不是答案,但在 MySQL 和 MongoDB 之间进行选择时,速度不应该是主要考虑因素。诸如无模式与模式(即您的数据模式需要多久更改一次)和规模缩放(即,将数据分片以使典型的读取仅需要来自一台服务器的数据的难易程度)之类的事情对于选择更为重要像这样。
怎样才能让阅读速度更快?它从机械设备中读取。与 MySQL 相同。这取决于设备本身的速度,您不能通过代码使用一些奇怪的魔法来突破硬件的限制。
@ImranOmarBukhsh,确实如此。我的观点来自不建议为了改变而改变 - 并提出一种可以利用现有技术提高性能的方法:)
这个问题让我想起了这一点:mongodb-is-web-scale.com
人们误以为他们会选择一个或另一个。你的厨房里需要微波炉和烤箱。你不能说我只会使用一个或另一个。两个系统的用例不同。如果您的应用程序的一部分需要 ACID,则使用 RDBMS,如果不关心一致性和约束并且您的实体可以存储为一体(集合),则使用 MongoDB。您最终将使用混合系统,关键是决定将什么存储在哪里。

S
Sean Reilly

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 相比,MySQL 每次逻辑访问的 IO 大约是 20 倍。

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


如果我们只在mysql中放一个主表怎么办?
@ariso:这是通过非规范化进行的优化。它可以提供性能提升。但是,如果您这样做,那么您将丢弃您的简洁设计,以及关系数据库的所有功能(更不用说大多数功能)。它只有在你达到列限制之前才真正起作用。
@SeanReilly 您的实体示例(应使用对象进行编辑,没有面向实体的编程:))无效。就像 ariso 所说,您可以序列化一个对象并将其存储在数据库中,并在需要时反序列化(任何形式的序列化)。持久对象的真正威力在于 oodbms 而不是文档数据库系统。但是我同意每个人都有自己的目的和优势(但是您的示例更加模糊了该主题的愿景和相关性)。
我想说,20 次连接很可能不是对最好的数据库模式的最好查询。
@SeanReilly 我发现您的示例非常有帮助。您可以为 MySQL 构建一个特殊的接口,该接口自动将对象序列化和反序列化为表,并按照 mongodb 的方式运行。但是,为什么不直接使用专门设计用于这种方式的东西呢?您对“实体”的使用也很有意义。关键是您将数据组织为文档而不是表中的字段。文档是否是用 OO 语言组成的对象与示例无关。
t
theAndroid

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

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

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

这真的应该是您测试的一部分:并发和 MySQL 引擎。然后,数据/模式设计和应用程序需求当然是巨大的需求,超出了响应时间。当你得到结果时让我知道,我也需要这方面的投入!


你能分享你的结果吗?
是的,结果将非常有帮助
当然,这只会扩大规模……如果是苹果对苹果,就像他们在本主题的其余部分中所说的那样。因此,如果它在 avg 上执行 x,现在从多个来源进行模拟,请解释为什么 mongo 会更快。也就是说,为了达成协议,mysql 在单个请求中的平均速度更快......为什么 mongo 现在对于多个请求会变得更快?我觉得这不是很科学。我说测试是有效的.. 但如果您像本主题的其余部分解释的那样将苹果与苹果进行比较,则不太确定差异会有多大。
A
Aritz

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

15 分钟插入 10,000 行?那是一个非常贫乏的 MySQL 数据库。根据我的经验,如果这样的操作持续时间接近 1 秒,我的手机就会亮起抱怨。 :)
几点: 1)Mysql需要优化配置好,插入大量数据的方式有很多种,如果做得好的话,15min的时间只有0.1%,例如this page。 2) MongoDB 不会立即将数据写入磁盘,这就是它“看起来”更快的原因,但如果您的计算机崩溃,数据就会丢失。 3) MySQL 的读取速度要快得多
10.000 行需要 15 分钟?你输入每一行? =))))
对于 10,000 行 - 删除索引、插入、重新索引
任何相信将 10 行插入 mysql 需要 1.7 秒的说法的人都应该得到从 mongo 那里得到的痛苦
r
reoxey

https://github.com/reoxey/benchmark

基准

GOLANG1.6 & PHP5 MySQL & MongoDB 速度对比

用于基准测试的系统:DELL cpu i5 4th gen 1.70Ghz * 4 ram 4GB GPU ram 2GB

RDBMS 与 NoSQL 对 INSERT、SELECT、UPDATE、DELETE 执行不同行数的速度比较 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

myisam不是innodb,还有哪个mongodb版本和存储引擎?
指定 MySQL 和 MongoDB 版本很重要。
不要使用 MyISAM。一定要使用批量插入!
MySQL 在 Insert 查询中比 Mongodb 快?!在 mysql 需要准备列和关系之前,这似乎不是真的。 mysql select比mongodb select快,但是在insert查询中,mongo更快
G
Gabe Rainbow

伙计,答案是您基本上是在测试 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 implode和in。

最后是这里发生了什么。看起来每次都创建一个连接,因此它测试连接时间加上查询时间。

$m = new Mongo();

对比

$db = new AQLDatabase();

因此,对于去除爵士乐的基础查询,您的 101% 的速度可能会提高 1000%。

呃。


自然,编码练习可以在任何情况下产生很大的不同,但这并不特定于任何类型的语言、api 或扩展。在启动计时器之前生成随机数会有所不同,但进程内的大部分时间无疑来自数据库事务。随机数生成很简单,SQL 和 NoSQL 数据库则不然。
不要选择兰特号码。显然,您每次都错过了创建连接。所有问题加起来都会测试超出预期的东西。
不,没有错过。除非调用 mysqli_close(),否则 MySQL 在脚本完成之前不会关闭连接。否则,重复调用 mysqli_connect() 只会从当前资源表中提取现有的 mysql 资源,而不是提交新的连接过程。我不确定 AQLDatabase 对象是什么,但如果它使用 mysql lib(它可能会这样做),它将具有相同的行为。 MongoDB 扩展使用连接池,因此在脚本中多次创建 mongodb“连接”时会发生相同的基本情况。
我同意他的基准测试可能会有所不同,但它反映的基本结果与我见过的其他 MySQL 与 Mongo 基准测试相同。 Mongo 在插入时通常更快(对于更简单的插入要快得多),而 MySQL 在选择时通常更快。
诚然,我太粗暴了;正是“
”的 html 字符串 concat 真正“催促”了我。您不需要在测试中进行漂亮的打印。甚至迭代它似乎是一个 php 测试,而不是一个数据库测试。总体而言,AQLDatabase '可能/也许'时刻......更多的成分意味着更多的未知数。
J
Jason Hitchings

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

RDBMS 与 NoSQL:性能和扩展比较

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


u
user1034912

老实说,即使 MongoDB 速度较慢,MongoDB 肯定会让我和你的代码更快......无需担心愚蠢的表列、行或实体迁移......

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


不同意,你必须选择最合适的技术,而不是最容易编码的。因为您可以将所有内容保存到文本文件中,然后根本无需担心数据库:)
不同意。这是一个不费吹灰之力的举动。 MongoDB 不能执行事务,而 MySQL 可以。这为我节省了很多编码,其中在 mongo 中,我必须在应用程序上编写一个功能块来执行它。所以你真的需要非常仔细地考虑每个系统的设计。两者都有其优点和缺点。
关于更快的编码也有争议,这是主观的。有些人更喜欢 ORM 和微 ORM,以自动管理模型更改和/或迁移,这导致开发人员只在一个地方(数据库)管理模式,就像在应用层中管理模式一样。
F
Fawaz Ahmed

来自 MongoDB 官方网站

观察两个系统的一些高级查询行为,我们可以看到 MySQL 在选择大量记录时速度更快,而 MongoDB 在插入或更新大量记录时明显更快。

Reference


z
zhuomin chen

在单服务器上,MongoDb 在读取和写入方面都不会比 mysql MyISAM 快,因为表/文档的大小很小,只有 1 GB 到 20 GB。 MonoDB 在多节点集群上的 Parallel Reduce 上会更快,而 Mysql 无法水平扩展。


您能否提供一些证据或更多细节来支持这一点?
不能水平缩放?新开发银行呢? DRBD 支持 MySQL?
这不是真的。 MongoDB 有 16MD 文档限制。如果你愿意,Mysql 可以有更多