MongoDB, сложные запросы и производительность - PullRequest
6 голосов
/ 26 октября 2010

Back-Story

В текущем проекте я использую MySQL и SQLite в сочетании друг с другом.В настоящее время я даю каждому пользователю свою собственную базу данных SQLite, чтобы обойти ограничение MySQL DB моего провайдера в 1 ГБ.Он хорошо работает и производительность хорошая, но я точно знаю, что постоянное обслуживание этих баз данных с плоскими файлами в будущем станет кошмаром.

SQLite на удивление мощен и поддерживает довольно сложный SQLзапросы.Тем не менее, я смотрю на MongoDB, чтобы прыгнуть на борт с небольшим NoSQL для объемных данных моего пользователя. Каждый пользователь может генерировать 60 000 или более строк. В связи с постоянно растущим числом пользователей я могу беспокоиться о производительности в будущем.

-

Сложность

Мое беспокойство по поводу MongoDB и других баз данных NoSQL заключается в том, что они кажутся более ограниченными в том, какие операции запросов они поддерживают.Ничего страшного, если вам просто нужны простые, простые массовые запросы, однако мне нужно выполнить более сложные объединения и фильтрацию (объединения, чувствительность к регистру, группировки, случайное объединение и т. Д.).

Мой пример запроса пытается выбрать список треков по исполнителю.Основная проблема в том, что имена этих художников могут не совпадать с .Например, некоторые люди помечают как «День, чтобы помнить», а некоторые люди помечают как «День К Помните».В случае запроса с учетом регистра это приводит к возвращению нескольких «разных», но на самом деле одинаковых вещей.Обычно я обрезаю и УСТАВЛЯЮ () поля, чтобы правильно сгруппировать их.

-

Производительность

Я создал две новые базы данных на своем локальном компьютере.Один для MongoDB, а другой для MySQL.Я говорю с ними на PHP, так как это то, что мой конечный результат должен будет использовать.Каждая база данных содержит только около 9 000 записей, поэтому на данный момент она не очень большая.

Я провел несколько тестов на своей машине и получил неутешительные результаты для MongoDB.Давайте рассмотрим эти три запроса ...

# 1 - MongoDB: ~ 14 мс, неверные результаты

$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: ~ 170 мс,правильные результаты

$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: ~ 18 мс, правильные результаты

$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 убивает его .Здесь нет даже очень большого количества записей, чтобы справиться с ними: чуть менее 9000 во всей базе данных.

Мой главный вопрос: : что будет более надежным иисполнитель в конце концов и до сих пор удовлетворить мои потребности?По мере роста пользовательской базы моего проекта я собираюсь покинуть свой ограниченный сервер и в любом случае получить что-то выделенное.С моей собственной установкой MySQL я должен иметь возможность поддерживать свои собственные большие таблицы MyISAM с небольшим количеством реляционных данных и надлежащим индексированием.

Но с миллионами записей в базе данных, что происходит с производительностью MySQL?Мысли, комментарии и общие обсуждения по этому поводу приветствуются.Спасибо!

Ответы [ 3 ]

8 голосов
/ 27 октября 2010

Попробуйте с регулярным выражением:

$regex = new MongoRegex('/^' . preg_quote('a day to remember'). '$/i');
$query = array('artist' => $regex);
$cursor = $collection->find($query);
6 голосов
/ 26 октября 2010

Вы должны сохранить значение дважды, если вы хотите выполнить поиск без учета регистра этого значения в Mongodb. Один раз в обычном режиме и один раз в нижнем регистре для индексации и поиска.

Mongodb имеет богатый язык запросов (по сравнению с другими системами nosql), и вы можете индексировать каждый (комбинацию) столбцов. Однако я считаю, что mapreduce медленный, но пока вы можете решить свою проблему без mapreduce, у вас все в порядке.

4 голосов
/ 26 октября 2010

Различные решения NoSQL отличаются друг от друга гораздо больше, чем традиционные базы данных SQL, но MongoDB на самом деле является одним из самых многофункциональных из множества, особенно когда речь идет о сложности запросов.

Однако вам не следует слепо выбирать решение NoSQL только потому, что вы ожидаете 60 000 строк на пользователя. MySQL и другие популярные реляционные СУБД могут без проблем обрабатывать миллиарды строк.

Реляционные базы данных имеют множество важных функций (например, ACID гарантирует и сложные запросы), и если вам нужны эти функции, вы также можете использовать базу данных SQL. NoSQL обычно является компромиссом между некоторыми из этих функций (или всеми ними) и простотой горизонтальной масштабируемости. Если вы можете рассчитывать на решение проблемы масштабируемости вашей системы с помощью реляционной СУБД, я бы серьезно подумал о том, чтобы придерживаться SQL.

В настоящее время я даю каждому пользователю свою собственную базу данных SQLite, чтобы обойти ограничение MySQL для моего провайдера в 1 ГБ.

Вы также можете рассмотреть вопрос о смене провайдеров. Хост, который применяет такие ограничения, вероятно, в конечном итоге ограничит вас каким-либо другим способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...