Каковы плюсы и минусы выполнения вычислений в sql в вашем приложении - программирование

Каковы плюсы и минусы выполнения вычислений в sql в вашем приложении

shopkeeper таблица имеет следующие поля:

id (bigint),amount (numeric(19,2)),createddate (timestamp)

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

Один из способов сделать - выполнить вычисления в моем приложении Java и выполнить простой запрос

Date previousDate ;// $1 calculate in application

Date todayDate;// $2 calculate in application

select amount where createddate between $1 and $2 

а затем пропустите записи и преобразуйте сумму в центы в моем приложении Java и создайте отчет

Другой способ - выполнить вычисления в самом sql-запросе:

select cast(amount * 100 as int) as "Cents"
from shopkeeper  where createddate  between date_trunc('day', now()) - interval '1 day'  and  date_trunc('day', now())

а затем прокрутите записи и создайте отчет

В одном случае вся моя обработка выполняется в java-приложении и запускается простой запрос. В других случаях все преобразования и вычисления выполняются в запросе Sql.

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

Не могли бы вы рассказать мне, какой подход лучше с точки зрения производительности и других аспектов и почему?

4b9b3361

Ответ 1

Это зависит от множества факторов - но наиболее важно:

  • сложность вычислений (предпочитайте делать сложный хруст на app-сервере, поскольку это масштабируется, а не сервер db, который масштабируется)
  • объем данных (если вам нужно получить доступ/собрать много данных, выполнение этого на сервере db позволит сэкономить полосу пропускания и диск io, если агрегаты могут быть сделаны внутри индексов)
  • удобство (sql - не лучший язык для сложной работы - особенно не очень подходит для процедурной работы, но очень хорош для работы на основе набора, однако, отвратительная обработка ошибок)

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

Повторите свое примечание:

а затем прокрутите записи

Циклирование по записям - это почти всегда неправильная работа в sql - предпочтительнее писать операцию на основе набора.

Как правило, я предпочитаю, чтобы задание базы данных было минимальным: "Храните эти данные, извлекайте эти данные", однако всегда есть примеры сценариев, в которых элегантный запрос на сервере может сэкономить большую пропускную способность.

Также подумайте: если это вычислительно дорого, можно ли его кэшировать где-то?

Если вам нужен точный "лучше"; код в обоих направлениях и сравнить его (отметив, что первый вариант либо, скорее всего, не на 100% настроен). Но фактор типичного использования для этого: если на самом деле его называют 5 раз (отдельно) сразу, то имитируют это: не сравнивайте ни одного "1 из этих vs 1 из них".

Ответ 2

Позвольте мне использовать метафору: если вы хотите купить золотое ожерелье в Париже, ювелир может сидеть в Кейптауне или Париже, это вопрос мастерства и вкуса. Но вы никогда не отправляли тонны золотой руды из Южной Африки во Францию ​​за это. Руда обрабатывается на участке добычи (или, по крайней мере, в общей зоне), только золото отгружается. То же самое должно быть верно для приложений и баз данных.

Что касается PostgreSQL, вы можете сделать почти что угодно на сервере, достаточно эффективно. СУБД превосходит сложные запросы. Для процедурных потребностей вы можете выбрать из серверных script языков: tcl, python, perl и многие другие. В основном я использую PL/pgSQL.

В худшем случае сценарий должен был бы постоянно переходить на сервер для каждой отдельной строки большего набора. (Это будет похоже на отгрузку одной тонны руды за раз.)

Второй в строке, если вы отправляете каскад запросов, каждый из которых зависит от предыдущего, а все это можно сделать в одном запросе или процедуре на сервере. (Это подобно доставке золота и каждой из драгоценностей с отдельным кораблем последовательно).

Переход между приложением и сервером стоит дорого. Для сервера и клиента. Попытайтесь сократить это, и вы выиграете - ergo: при необходимости используйте процедуры на стороне сервера и/или сложный SQL.

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

Ответ 3

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

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

Где это имеет значение:

  • Совокупные вычисления, такие как SUM(), AVG(), MIN(), MAX(), здесь механизм базы данных будет на порядок быстрее, чем реализация Java.
  • В любом месте вычисление используется для фильтрации строк. Фильтрация в БД намного эффективнее, чем чтение строки, а затем ее отбрасывание.

Ответ 4

Нет черных/белых относительно того, какие части логики доступа к данным должны выполняться в SQL и какие части должны выполняться в вашем приложении. Мне нравится формулировка Марка Гравелла, различая

  • сложные вычисления
  • расчеты с использованием данных

Сила и выразительность SQL сильно недооцениваются. Начиная с введения функций многие нестрого ориентированные вычисления могут быть выполнены очень легко и элегантно в базе данных.

Следует соблюдать три правила большого пальца, независимо от общей архитектуры приложения:

  • сохранить объем данных, передаваемых между базой данных и приложением slim (в пользу вычисления данных в БД)
  • сохранить объем данных, загруженных с диска, с помощью slim базы данных (в пользу того, чтобы позволить операторам оптимизировать базу данных, чтобы избежать ненужного доступа к данным)
  • не подталкивайте базу данных к ее предельным значениям ЦП с помощью сложных параллельных вычислений (в пользу вытаскивания данных в память приложения и выполнения там расчетов)

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

Дальнейшее чтение, где объясняются эти вещи:

Ответ 5

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

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

Ответ 6

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

Подумайте об этом в два этапа: (1) OLTP (небольшое количество записей) транзакций. (2) OLAP (длительное сканирование многих записей).

В случае OLTP, если вы хотите быть быстрым (10 тыс. - 100 тыс. транзакций в секунду), вы должны удалить блокировку, блокировку и блокировку блокировки из базы данных. Это означает, что вам необходимо устранить длинные киоски в транзакциях: однократные поездки от клиента к БД для перемещения обработки клиенту - это один такой длинный ларь. Вы не можете долго работать (чтобы сделать чтение/обновление атома) и иметь очень высокую пропускную способность.

Re: горизонтальное масштабирование. Современные базы данных масштабируются горизонтально. Эти системы уже реализуют HA и отказоустойчивость. Используйте это и попробуйте упростить свое прикладное пространство.

Посмотрите на OLAP - в этом случае должно быть очевидно, что перетаскивание, возможно, terrabytes данных обратно в приложение является ужасной идеей. Эти системы созданы специально для эффективной работы с сжатыми, предварительно организованными столбчатыми данными. Современные OLAP-системы также масштабируются по горизонтали и имеют сложные планировщики запросов, которые рассеивают работу по горизонтали (внутренняя обработка данных).

Ответ 7

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

  • Если вы можете добиться чего-то простого с помощью базы данных sql, тогда лучше подойдите к нему, поскольку db будет работать намного лучше и делать вычисления там, а затем с результатами выборки. Однако, если фактическое вычисление требует слишком большого вычисления отсюда и там, то вы можете пойти с кодом приложения. Зачем? Поскольку сценарий, подобный циклу, в большинстве случаев не лучше всего обрабатывается sql, где передние языки интерфейса лучше разработаны для этих целей.
  • В случае, если подобный расчет требуется из многих мест, тогда, очевидно, размещение кода вычисления на конце db будет лучше сохранить вещи в одном и том же месте.
  • Если для достижения окончательного результата много разных запросов необходимо выполнить множество вычислений, то также идем на конец db, так как вы можете поместить тот же код в хранимую процедуру, чтобы лучше работать, чем извлекать результаты из бэкэнд, а затем вычислять их на передней панели.

Есть много других аспектов, которые вы можете подумать, прежде чем решать, где разместить код. Одно восприятие совершенно неверно - все может быть сделано лучше всего на Java (код приложения) и/или все лучше всего делать с помощью db (код sql).

Ответ 8

Формируйте точку зрения производительности: это очень простая арифметическая операция, которая почти наверняка может выполняться намного быстрее, чем фактическое извлечение данных с дисков, которые находятся в основе базы данных. Кроме того, вычисление значений в предложении where может быть очень быстрым в любой среде выполнения. Таким образом, узким местом должен быть диск IO, а не вычисление значений.

В соответствии с читабельностью, я думаю, что если вы используете ORM, вы должны сделать это в своей среде сервера приложений, потому что ORM позволит вам работать с базовыми данными очень легко, используя операции на основе набора. Если вы все равно собираетесь писать raw SQL, нет ничего плохого в том, чтобы делать вычисления там, ваш SQL также выглядел бы немного лучше и легче читать, если отформатировать правильно.

Ответ 9

Реально, "производительность" не определена.

Наиболее важным для меня является время разработки.

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

Ответ 10

Я не считаю, что различия в производительности могут быть обоснованы без конкретных примеров и тестов, но у меня есть еще одно:

Что вы можете поддерживать лучше? Например, вы можете переключить свой интерфейс с Java на Flash или HTML5 или на С++ или что-то еще. Огромное количество программ прошли такое изменение или даже существуют на более чем одном языке для начала, потому что им необходимо работать на нескольких устройствах.

Даже если у вас есть правильный средний уровень (из приведенного примера, похоже, что это не так), этот слой может измениться, а JBoss может стать Ruby/Rails.

С другой стороны, маловероятно, что вы замените SQL-backend тем, что не является реляционной БД с SQL, и даже если вы это сделаете, вам все равно придется переписывать интерфейс с нуля, поэтому точка является спорным.

Моя идея состоит в том, что если вы выполняете вычисления в БД, гораздо легче будет написать второй интерфейс или средний слой позже, потому что вам не нужно повторно выполнять все. На практике, однако, я думаю, что "где я могу это сделать с кодом, который люди поймут" является самым важным фактором.

Ответ 11

Чтобы упростить ответ на этот вопрос, нужно посмотреть на балансировку нагрузки. Вы хотите поставить нагрузку там, где у вас больше всего возможностей (если это имеет смысл). В большинстве систем SQL-сервер быстро становится узким местом, поэтому, вероятно, ответ заключается в том, что вы не хотите, чтобы SQL выполнял одну унцию работы больше, чем нужно.

Также в большинстве архитектур это SQL-сервер (ы), которые составляют ядро ​​системы и внешних систем, которые добавляются.

Но приведенная выше математика настолько тривиальна, что, если вы не подталкиваете свою систему к пределу, лучше всего разместить ее там, где вы хотите ее поместить. Если математика не была тривиальной, такой как вычисление sin/cos/tan, например, расчет расстояния, тогда усилие может стать нетривиальным и требует тщательного планирования и тестирования.

Ответ 12

Другие ответы на этот вопрос интересны. Удивительно, но никто не ответил на ваш вопрос. Вам интересно:

  • Лучше ли использовать Quents в запросе? Я не думаю, что актеры к центам добавляет что-либо в ваш запрос.
  • Лучше ли использовать запрос now() в запросе? Я предпочел бы передавать даты в запросе, а не вычислять их в запросе.

Дополнительная информация: Для первого вопроса вы хотите быть уверенным, что объединение фракций  работает без ошибок округления. Я думаю, что числовое 19,2 является разумным  за деньги, а во втором случае целые числа в порядке. По этой причине использование поплавка за деньги не так.

Для второго вопроса мне нравится иметь полный контроль как программист того, что  дата считается "сейчас". Трудно записать автоматический блок  тесты при использовании таких функций, как now(). Кроме того, когда у вас больше  транзакции script может быть полезно установить переменную, равную now(), и использовать переменную so  что вся логика использует то же самое значение.