В настоящее время я работаю над приложением PHP (предварительная версия).
Фон
У нас есть таблица в нашей базе данных MySQL, которая, как ожидается, станет чрезвычайно большой — для одного пользователя было бы весьма необычно иметь 250 000 строк в этой таблице. Каждой строке в таблице, среди прочего, присваивается сумма и дата.
Кроме того, эта конкретная таблица читается (и записывается) очень часто — на большинстве страниц. Учитывая, что в каждой строке есть дата, я использую GROUP BY date
чтобы минимизировать размер результирующего набора, заданного MySQL, теперь строки, содержащиеся в одном и том же году, можно рассматривать как одно целое.
Тем не менее, типичная страница по-прежнему будет иметь набор результатов между 1000-3000 результатов. Есть также места, где много SUM()
Выполняются десятки, если не сотни тысяч строк.
Пробовать MySQL
На обычной странице MySQL обычно занимал около 600-900 мс. С помощью LIMIT
и смещения не помогали производительности, а данные были сильно нормализованы, и, следовательно, дальнейшая нормализация не помогла бы.
Что еще хуже, есть части приложения, которые требуют извлечения 10000-15000 строк из базы данных. Результаты затем используются в вычислениях PHP и форматируются соответствующим образом. Учитывая это, производительность MySQL не была приемлемой.
Попытка MongoDB
Я преобразовал таблицу в MongoDB, и ее скорость выше — обычно для извлечения 2000 документов требуется около 250 мс. Тем не менее $group
команда в конвейере агрегации — необходимая для агрегирования полей в зависимости от года, в который они попадают — замедляет работу. К сожалению, сохранение итогов и обновление информации о том, что всякий раз, когда документ удаляется / обновляется / вставляется, также не обсуждается, поскольку, хотя мы можем использовать итоговую сумму за год для некоторых частей приложения, в других частях для расчетов требуется, чтобы каждая сумма приходилась на конкретная дата.
Я также рассмотрел Redis, хотя я думаю, что сложность данных выходит за рамки, для которых Redis был разработан.
Последняя соломинка
Помимо всего этого, скорость важна. Таким образом, производительность на первом месте с точки зрения приоритетов.
Вопросы:
Я немного застрял на данный момент, я не смог получить такой большой набор результатов за приемлемое количество времени. Кажется, что большинство хранилищ данных отлично подходят для небольших размеров поиска — даже для больших объемов данных — но я не смог ничего найти при извлечении больших объемов данных из еще более крупной таблицы / коллекции.
Я только прочитал первые две строки, но вы используете агрегацию (GROUP BY
) а потом чего ожидать просто в реальном времени?
Я скажу, что вы новичок во внутренних базах данных, чтобы не подорвать вас, а попытаться помочь вам.
Оператор группы в MySQL и MongoDB находится в памяти. Другими словами, он принимает любую структуру данных, которую вы представляете, будь то индекс или документ (строка), и он будет проходить через каждую строку / документ, занимая поле и группируя его.
Это означает, что вы можете ускорить его как в MySQL, так и в MongoDB, убедившись, что вы используете индекс для группировки, но, тем не менее, это еще далеко, даже при размещении индекса в вашем прямом рабочем наборе в MongoDB (память).
Фактически используя LIMIT
с OFFSET
также, вероятно, просто замедляет ситуацию еще более откровенно. Поскольку после выписывания набора MySQL необходимо выполнить запрос еще раз, чтобы получить ваш ответ.
После этого он запишет результат, MySQL запишет его в набор результатов (здесь используется память и ввод-вывод), а MongoDB ответит встроенным, если вы не установили $out
максимальный размер встроенного вывода составляет 16 МБ (максимальный размер документа).
Последний пункт, который нужно забрать здесь: агрегация ужасна
Здесь нет серебряной пули, которая вас спасет, некоторые базы данных будут пытаться похвастаться своей скоростью и т. Д. И т. Д., Но факт заключается в том, что большинство крупных агрегаторов используют так называемые «предварительно агрегированные отчеты». Вы можете найти краткое введение в документации MongoDB: http://docs.mongodb.org/ecosystem/use-cases/pre-aggregated-reports/
Это означает, что вы прикладываете усилия для агрегации и группировки в какой-то другой процесс, который мог бы сделать это достаточно легко, позволяя вашему потоку чтения быть тем, который должен быть в реальном времени, чтобы выполнять его в реальном времени.
Других решений пока нет …