我对 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;
}
?>
:)
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 在某些用例中提高性能的方式。
你有并发,即同时用户吗?如果你只用一个线程直接运行 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)
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
伙计,答案是您基本上是在测试 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%。
呃。
这是使用 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 数据库作为替代方案,同时考虑到更大的数据库大小导致的存储成本和内存大小。
老实说,即使 MongoDB 速度较慢,MongoDB 肯定会让我和你的代码更快......无需担心愚蠢的表列、行或实体迁移......
使用 MongoDB,您只需实例化一个类并保存!
在单服务器上,MongoDb 在读取和写入方面都不会比 mysql MyISAM 快,因为表/文档的大小很小,只有 1 GB 到 20 GB。 MonoDB 在多节点集群上的 Parallel Reduce 上会更快,而 Mysql 无法水平扩展。
不定期副业成功案例分享