MongoDB,复杂查询和性能

时间:2010-10-26 18:23:07

标签: php sql mongodb sqlite nosql

背景故事

在当前项目中,我将MySQL和SQLite相互结合使用。我目前正在为每个用户提供他们自己的SQLite数据库来绕过我的提供商的1GB MySQL数据库限制。它运行良好,性能良好,但我知道这些平面文件数据库的持续维护将成为未来的噩梦。

SQLite功能强大,支持一些非常复杂的SQL查询。但是,我正在寻找MongoDB,为我的用户的批量数据添加一些NoSQL。 每个用户可以生成60,000行或更多。随着用户数量的不断增加,我将来会担心性能。

-

复杂性

我对MongoDB和其他NoSQL数据库的担心是,它们在支持哪种查询操作时似乎更受限制。如果你只是需要直接,简单的批量查询,这没什么大不了的,但是我必须做一些更复杂的加入和过滤(联合,区分大小写,分组,偶尔加入等等)。

我的示例查询尝试按艺术家选择曲目列表。主要问题是这些艺术家名称可能不匹配。例如,某些人标记为“A Day to Remember”,有些人标记为“A day To Remember”。使用区分大小写的查询,这会导致多个“不同”的记录但实际上是相同的记录。通常我修剪和LOWER()字段以正确地将它们组合在一起。

-

效果

我在本地计算机上创建了两个全新的数据库。一个用于MongoDB,一个用于MySQL。我正在和他们用PHP交谈,因为这是我的最终结果必须使用的。每个数据库中只有大约9,000条记录,所以此时它并不是非常大。

我在我的机器上运行了一些测试,并为MongoDB提供了令人失望的结果。让我们考虑这三个问题......

#1 - MongoDB:~14ms,结果不正确

$query = array('artist' => 'A Day to Remember');
$cursor = $collection->find($query);
foreach ($cursor as $row) {
    echo $row['artist'] . ' - ' . $row['album'] . ' - #'. $row['track'] . ' ' . $row['title'] . "\r\n";
}

#2 - MongoDB:~170ms,结果正确

$query = array('$where' => "this.artist.toLowerCase() == 'a day to remember'");
$cursor = $collection->find($query);
foreach ($cursor as $row) {
    echo $row['artist'] . ' - ' . $row['album'] . ' - #'. $row['track'] . ' ' . $row['title'] . "\r\n";
}

#3 - MySQL:~18ms,结果正确

$sql = "select artist, album, track, title from radio_files where lower(artist) = 'a day to remember'";
$stmt = $mysqldb->prepare($sql);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
    echo $row['artist'] . ' - ' . $row['album'] . ' - #'. $row['track'] . ' ' . $row['title'] . "\r\n";
}

-

讨论

也许我只是没有正确查询#2,但只看Javascript查询引擎如何杀死它。这里总共没有很多记录要处理:所有数据库中的记录都不到9,000。

我的主要问题是:最终会更加可靠和高效并且仍然适合我的需求?随着我的项目用户群的增长,我希望离开我的有限服务器并获得一些专用的东西。使用我自己的MySQL安装,我应该能够维护自己的大型MyISAM表,只需要很少的关系数据和正确的索引。

但是数据库中有数百万条记录,MySQL的性能会怎样?鼓励对此进行思考,评论和一般性讨论。谢谢!

3 个答案:

答案 0 :(得分:8)

尝试使用正则表达式:

$regex = new MongoRegex('/^' . preg_quote('a day to remember'). '$/i');
$query = array('artist' => $regex);
$cursor = $collection->find($query);

答案 1 :(得分:6)

如果要在Mongodb中对此值进行不区分大小写的搜索,则必须存储两次值。一旦正常,一次用小写进行索引和搜索。

Mongodb具有丰富的查询语言(与其他nosql系统相比),您可以索引列的每个(组合)。但是我确实发现mapreduce很慢,但是只要你没有mapreduce就可以解决你的问题,你很好。

答案 2 :(得分:4)

不同的NoSQL解决方案之间的区别远远超过传统的SQL数据库,但MongoDB实际上是功能最丰富的解决方案之一,尤其是在查询复杂性方面。

但是,您不应该盲目地选择NoSQL解决方案,因为您希望每个用户有60,000行。 MySQL和其他流行的关系型DBMS可以毫无问题地处理数十亿行。

关系数据库具有许多重要功能(例如ACID保证和复杂查询),如果您需要这些功能,您也可以使用SQL数据库。 NoSQL通常是其中一些功能(或所有功能)之间的权衡,以及水平可扩展性的简易性。如果您可以期望使用关系DBMS管理系统的可伸缩性问题,那么我会认真考虑坚持使用SQL。

  

我目前正在为每个用户提供他们自己的SQLite数据库,以解决我的提供商的1GB MySQL数据库限制。

您也可以考虑转换提供商。应用此类限制的主机最终可能会以其他方式限制您。

相关问题