Але чи це насправді важливо? Подумайте, що інтерфейс повинен здійснити мережевий дзвінок в 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% вашого трафіку займає тривалий час через ще не виявлений цикл, який викликає базу даних 10 000 разів.
- Іноді є речі, в яких ваша програма краще, наприклад, деякі складні розрахунки. Можливо, вам доведеться прочитати деякі дані з бази даних, зробити деякі обчислення, потім на основі результатів передати параметр на другий виклик бази даних (можливо, щоб записати деякі результати). Якщо ви об'єднаєте їх в один виклик (як збережена процедура) лише для того, щоб лише один раз викликати базу даних, ви змусили себе використовувати базу даних для того, на чому може бути кращим сервер додатків.
- Балансування завантаження: у вас є 1 база даних (імовірно) і кілька серверів додатків, збалансованих навантаженням. Таким чином, чим більше робота робить додаток, і тим менше буде база даних, тим простіше його масштабувати, оскільки додавати сервер додатків, як правило, простіше, ніж реплікацію бази даних. Виходячи з попередньої точки кулі, може мати сенс запустити SQL-запит, потім виконати всі обчислення в додатку, який розподіляється на декілька серверів, а потім записати результати, коли закінчите. Це може забезпечити кращу пропускну здатність (навіть якщо загальний час транзакції однаковий).
TL; DR
TLDR: Чи дійсно важливо турбуватися про багаторазові дзвінки до бази даних, коли ми вже здійснюємо мережевий дзвінок через локальну мережу? Якщо так, то чому?
Так, але лише певною мірою. Ви повинні намагатися мінімізувати кількість дзвінків до бази даних, коли це практично, але не комбінувати дзвінки, які не мають нічого спільного між собою лише заради їх поєднання. Крім того, уникайте дзвінків до бази даних у циклі за будь-яку ціну.