Но так ли это важно? Учтите, что пользовательский интерфейс должен выполнить сетевой вызов API; это довольно большой (порядка миллисекунд). Базы данных оптимизированы для того, чтобы хранить вещи в памяти и выполнять чтение очень и очень быстро (например, SQL Server загружает и сохраняет все в оперативной памяти и потребляет почти всю свободную оперативную память, если это возможно).
Логика
В теории вы правы. Однако есть несколько недостатков с этим обоснованием:
Из того, что вы заявили, неясно, действительно ли вы тестировали / профилировали свое приложение. Другими словами, знаете ли вы , что передача по сети из приложения в API - самый медленный компонент? Поскольку это интуитивно понятно, легко предположить, что это так. Тем не менее, при обсуждении производительности, вы никогда не должны предполагать. У моего работодателя я лидер по производительности. Когда я впервые присоединился, люди продолжали говорить о CDN, репликации и т. Д., Основываясь на интуиции о том, какими должны быть узкие места. Оказывается, самыми большими проблемами с производительностью были плохо выполняемые запросы к базе данных.
Вы говорите, что поскольку базы данных хороши для извлечения данных, база данных обязательно работает с максимальной производительностью, используется оптимально, и ничего нельзя сделать, чтобы улучшить ее. Другими словами, базы данных спроектированы так, чтобы быть быстрыми, поэтому мне никогда не придется беспокоиться об этом. Еще одна опасная линия мышления. Это все равно, что сказать, что машина должна двигаться быстро, поэтому мне не нужно менять масло.
Такое мышление предполагает один процесс за раз, или, другими словами, без параллелизма. Предполагается, что один запрос не может влиять на выполнение другого запроса. Совместно используемые ресурсы, такие как дисковый ввод-вывод, пропускная способность сети, пулы соединений, память, циклы ЦП и т. Д. Следовательно, сокращение использования общего ресурса одним вызовом базы данных может предотвратить замедление других запросов. Когда я впервые присоединился к своему нынешнему работодателю, руководство полагало, что настройка 3-секундного запроса к базе данных была пустой тратой времени. 3 секунды это так мало, зачем тратить на это время? Разве нам не лучше с CDN или компрессией или чем-то еще? Но если я смогу выполнить 3-секундный запрос за 1 секунду, скажем, с помощью добавления индекса, это на 2/3 меньше блокирования, на 2/3 меньше времени, занимаемого потоком, и, что более важно, меньше данных, считываемых с диска,
Теория
Существует распространенное мнение, что производительность программного обеспечения зависит только от скорости .
С точки зрения скорости, вы правы. Система работает так же быстро, как ее самый медленный компонент. Если вы профилировали свой код и обнаружили, что Интернет - самый медленный компонент, то все остальное, очевидно, не самая медленная часть.
Однако, учитывая вышесказанное, я надеюсь, вы увидите, как конфликт ресурсов, отсутствие индексации, плохо написанный код и т. Д. Могут привести к неожиданным различиям в производительности.
Предположения
Последняя вещь. Вы упомянули, что вызов базы данных должен быть дешевым по сравнению с сетевым вызовом из приложения в API. Но вы также упомянули, что приложение и серверы API находятся в одной локальной сети. Таким образом, они не сопоставимы как сетевые вызовы? Другими словами, почему вы предполагаете, что передача API на несколько порядков медленнее, чем передача базы данных, когда они имеют одинаковую доступную пропускную способность? Конечно, протоколы и структуры данных разные, я понимаю, но я оспариваю предположение, что они различаются на несколько порядков.
Откуда это чертовски
Весь этот вопрос о «множественных» или «единичных» вызовах базы данных. Но неясно, сколько их несколько. Из-за того, что я сказал выше, как общее практическое правило, я рекомендую делать как можно меньше вызовов базы данных. Но это только эмпирическое правило.
Вот почему:
- Базы данных отлично подходят для чтения данных. Это двигатели хранения. Однако ваша бизнес-логика живет в вашем приложении. Если вы создаете правило, согласно которому каждый вызов API приводит к одному вызову базы данных, ваша бизнес-логика может оказаться в базе данных. Может быть, это нормально. Многие системы делают это. Но некоторые этого не делают. Это о гибкости.
- Иногда, чтобы добиться хорошего разделения, нужно разделить 2 вызова базы данных. Например, возможно, каждый HTTP-запрос направляется через общий фильтр безопасности, который проверяет из БД, что у пользователя есть права доступа. Если это так, перейдите к выполнению соответствующей функции для этого URL. Эта функция может взаимодействовать с базой данных.
- Вызов базы данных в цикле. Вот почему я спросил, сколько это кратно. В приведенном выше примере у вас будет 2 вызова базы данных. 2 в порядке. 3 может быть хорошо. N не в порядке. Если вы вызываете базу данных в цикле, вы теперь сделаете производительность линейной, что означает, что она будет занимать больше времени, чем больше входных данных цикла. Строго говоря, говоря, что время сети API является самым медленным, полностью игнорирует аномалии, например, 1% вашего трафика, что занимает много времени из-за еще не обнаруженного цикла, который вызывает базу данных 10000 раз.
- Иногда есть вещи, в которых ваше приложение лучше, например, сложные вычисления. Возможно, вам потребуется прочитать некоторые данные из базы данных, выполнить некоторые вычисления, а затем на основе результатов передать параметр во второй вызов базы данных (возможно, чтобы записать некоторые результаты). Если вы объединяете их в один вызов (например, хранимую процедуру) только ради одного вызова базы данных, вы заставляете себя использовать базу данных для чего-то, в чем сервер приложений мог бы быть лучше.
- Балансировка нагрузки: у вас есть 1 база данных (предположительно) и несколько серверов приложений с балансировкой нагрузки. Следовательно, чем больше работы выполняет приложение и чем меньше база данных, тем легче ее масштабировать, поскольку обычно проще добавить сервер приложений, чем настроить репликацию базы данных. Исходя из предыдущего пункта, может иметь смысл выполнить SQL-запрос, затем выполнить все вычисления в приложении, которое распределено по нескольким серверам, и затем записать результаты после завершения. Это может повысить пропускную способность (даже если общее время транзакции одинаково).
TL; DR
TLDR: действительно ли важно беспокоиться о множественных вызовах базы данных, когда мы уже совершаем сетевой вызов по локальной сети? Если так, то почему?
Да, но только в определенной степени. Вы должны стараться свести к минимуму количество обращений к базе данных, когда это целесообразно, но не объединяйте вызовы, которые не имеют ничего общего друг с другом только ради их объединения. Кроме того, избегайте вызова базы данных в цикле любой ценой.