MongoDB,复杂查询和性能

joc*_*ull 6 php sql sqlite mongodb 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";
}
Run Code Online (Sandbox Code Playgroud)

#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";
}
Run Code Online (Sandbox Code Playgroud)

#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";
}
Run Code Online (Sandbox Code Playgroud)

-

讨论

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

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

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

Max*_*nce 8

尝试使用正则表达式:

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


TTT*_*TTT 6

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

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