Вы рассчитываете масштабируемые результаты на основе данных транзакций в веб-приложении?

Возможный дубликат:
Разработка базы данных: расчет баланса счета

Я работаю с веб-приложением, в котором хранятся данные транзакции (например, "сумма х на дату у", но более сложная) и предоставляются результаты расчетов на основе подробностей всех соответствующих транзакций [1]. Мы тратим много времени на то, чтобы эти вычисления выполнялись эффективно, поскольку они являются интерактивной частью приложения: то есть пользователь нажимает кнопку и ждет, чтобы увидеть результат. Мы уверены, что для текущих уровней данных мы можем оптимизировать выборку и вычисление базы данных, чтобы завершить ее в приемлемое время. Тем не менее, я обеспокоен тем, что по мере роста количества транзакций время будет расти линейно [2]. Я хотел бы сказать, что мы могли бы обрабатывать на порядок больше транзакций без чрезмерного снижения производительности.

Я ищу эффективные методы, технологии, шаблоны или алгоритмы, которые могут улучшить масштабируемость расчетов на основе данных транзакций.

Однако существуют реальные и существенные ограничения для любого предложения:

  • В настоящее время мы должны поддерживать две несовместимые реализации баз данных, MySQL и Oracle. Таким образом, например, использование специфичных для базы данных хранимых процедур примерно вдвое увеличивает стоимость обслуживания.
  • Фактические транзакции являются более сложными, чем приведенная в качестве примера транзакция, и бизнес-логика, используемая в вычислениях, является сложной и регулярно изменяется. Таким образом, хранение вычислений непосредственно в SQL - это не то, что мы можем легко поддерживать.
  • Любая из ранее сохраненных транзакций может быть изменена в любое время (например, дата транзакции может быть перенесена на год вперед или назад), а вычисления, как ожидается, будут обновлены мгновенно. Это имеет эффект для стратегий кэширования.
  • Пользователи могут запрашивать через большое пространство, в нескольких измерениях. Для объяснения рассмотрим возможность вычисления результата в том виде, в каком он будет в любой заданной дате, для любого конкретного типа транзакции, где транзакции фильтруются по нескольким произвольным условиям. Это затрудняет предварительный расчет результатов, которые пользователь хотел бы видеть.
  • Один экземпляр нашего приложения размещен в корпоративной сети клиента, на его оборудовании. Таким образом, мы не можем легко бросить деньги на проблему с точки зрения процессоров и памяти (даже если они на самом деле являются узким местом).

Я понимаю, что это очень открытый и общий, однако...

Есть ли предложения для достижения масштабируемого решения?

[1] Где "соответствующим" может быть: запрашиваемая дата; тип транзакции; тип пользователя; выбор формулы; и т.п.
[2] По общему признанию, это улучшение по сравнению с предыдущей производительностью, когда для задач ORM n+1 было показано, что затраченное время возрастало либо в геометрической прогрессии, либо, по крайней мере, в гораздо более крутом градиенте.

2 ответа

Решение

Я работал против аналогичных требований, и у меня есть несколько предложений. Многое зависит от того, что возможно с вашими данными. Трудно сделать все мыслимые случаи быстрыми, но вы можете оптимизировать их для общих случаев и иметь достаточно аппаратных средств для других.

Суммировать

Мы создаем резюме на ежедневной, еженедельной и ежемесячной основе. Для нас большинство транзакций происходит в текущий день. Старые транзакции также могут измениться. Мы держим batch и при этом индивид transaction записей. Каждая партия имеет статус, чтобы указать, если сводка транзакций (в таблице batch_summary) может быть использован. Если старая транзакция в суммированном пакете изменяется, как часть этой транзакции batch помечается, чтобы указать, что сводке нельзя доверять. Фоновое задание пересчитает сводку позже.

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

Мы поиграли с материализованными взглядами Oracle, но в итоге развернули наш собственный процесс обобщения.

Ограничить требования

Ваши требования звучат очень широко. Может возникнуть соблазн разместить все поля запроса на веб-странице и позволить пользователям выбирать любую комбинацию полей и выводить результаты. Это делает его очень сложным для оптимизации. Я бы посоветовал углубиться в то, что им на самом деле нужно делать или делалось в прошлом. Возможно, не имеет смысла запрашивать очень неселективные измерения.

В нашем приложении для определенных запросов речь идет об ограничении диапазона дат не более чем на 1 месяц. Мы согласовали некоторые функции с основанными на дате аннотациями. например, вы можете получить результаты за весь январь 2011 года, но не 5-20 января 2011 года.

Обеспечение обратной связи с пользовательским интерфейсом для медленных операций

В некоторых случаях нам было трудно оптимизировать некоторые вещи, чтобы они были короче, чем несколько минут. Мы переносим работу на фоновый сервер, а не на очень медленную загрузку веб-страницы. Пользователь может выполнить запрос и заняться своими делами, пока мы не получим ответ.

Я бы предложил использовать материализованные представления. Материализованные представления позволяют вам сохранять представления так же, как таблицы. Таким образом, все сложные запросы, которые вам нужно выполнить, предварительно рассчитываются до того, как пользователь их запросит.

Сложная часть, конечно, обновляет материализованное представление, когда таблицы основаны на изменениях. Здесь есть хорошая статья об этом: Обновите материализованное представление, когда меняются таблицы ссылок.

Материализованные представления (пока) не доступны без плагинов в MySQL и ужасно сложны для реализации в противном случае. Однако, поскольку у вас есть Oracle, я бы посоветовал проверить ссылку выше для того, как добавить Материализованное Представление в Oracle.

Другие вопросы по тегам