MySQL与MongoDB 1000读取

我对MongoDb非常兴奋,最近一直在测试它。我在MySQL中有一个名为posts的表,其中大约有2000万条记录只在一个名为“id”的字段上索引

我想将速度与MongoDB进行比较,并运行了一个测试,从我们庞大的数据库中随机获取并打印15条记录。我为mysql和MongoDB分别运行了大约1000次查询,我很惊讶我没有注意到在速度上有很大的差异。也许MongoDB的速度快了1.1倍。那太令人失望了。我做错什么了吗?我知道我的测试不是完美的,但是MySQL与MunGDB在读密集的事务时是一致的。p>

注:

  • 我有双核+(2个线程)i7CPU和4GB ram
  • 我在MySQL上有20个分区,每个分区有100万条记录

用于测试MongoDB的示例代码

<?php
函数microtime_float()
{
列表($usec,$sec)=爆炸(“,microtime());
返回((浮动)$usec+(浮动)$sec);
}
$time_take=0;
$trys=100;
//连接
$time_start=microtime_float();
对于($i=1;$i<=$trys;$i++)
{
$m=新的Mongo();
$db=$m->swalif;
$cursor=$db->posts->find(数组('id'=>数组('$in'=>get_15_random_number()));
foreach($光标为$obj)
{
//echo$obj[“线程标题”]。“<br><br>”;
}
}
$time_end=microtime_float();
$time\u taked=$time\u taked+($time\u end-$time\u start);
echo$花费的时间;
函数get_15_random_numbers()
{
$numbers=array();
对于($i=1;$i<=15;$i++)
{
$numbers[]=百万兰特(12000000);
}
返回$number;
}
?>

测试MySQL的示例代码

<?php
函数microtime_float()
{
列表($usec,$sec)=爆炸(“,microtime());
返回((浮动)$usec+(浮动)$sec);
}
$BASE_PATH=“../src/”;
包括一次($BASE_PATH.“classes/forumdb.php”);
$time_take=0;
$trys=100;
$time_start=microtime_float();
对于($i=1;$i<=$trys;$i++)
{
$db=新的AQLDatabase();
$sql=“select*from posts_really_big where id in(“.infrade(”,“,get_15_random_number())”);
$result=$db->executeSQL($sql);
while($row=mysql\u fetch\u数组($result))
{
//echo$行[“线程标题”]。“<br><br>”;
}
}
$time_end=microtime_float();
$time\u taked=$time\u taked+($time\u end-$time\u start);
echo$花费的时间;
函数get_15_random_numbers()
{
$numbers=array();
对于($i=1;$i<=15;$i++)
{
$numbers[]=百万兰特(12000000);
}
返回$number;
}
?>

MongoDB并没有神奇地更快。如果你存储相同的数据,以基本相同的方式组织,并以完全相同的方式访问,那么你真的不应该期望你的结果会有很大的不同。毕竟,MySQL和MongoDB都是GPL,所以如果Mongo中有一些神奇的更好的IO代码,那么MySQL团队就可以将其合并到他们的代码库中

人们看到真实世界中MongoDB的性能很大程度上是因为MongoDB允许您以一种对您的工作负载更敏感的方式进行查询

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

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

在MongoDB中,要检索整个实体,必须执行以下操作:

  • 集合上的一个索引查找(假设实体是通过id获取的)
  • 检索一个数据库页面的内容(实际的二进制json文档)

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

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

  • 根表上的一个索引查找(同样,假设实体是通过id获取的)
  • 对于聚集索引,我们可以假设根行的值在索引中
  • 实体pk值的20多个范围查找(希望在索引上)
  • 这些可能不是聚集索引,因此,一旦我们确定了适当的子行是什么,就会进行相同的20多个数据查找

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

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

因此,对于本例,与MongoDB相比,使用MySQL进行每个逻辑访问的最终IO数量大约是后者的20倍

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

发表评论