Надзвичайно цікава розповідь від Navneet Kumar Singh на dev.to про те, як йому довелося покроково розв'язувати проблему пов'язану з неоптимізованим запитом до БД під управлінням TypeORM.
Таблицю з більше ніж 700k записів та поганий запит до неї, час віддачі даних на фронт може сягати більш ніж 6 секунд. Безпосередньо сам запит не складний: 4 join, близько 4 where, sorting, limit та skip.
Для експериментів була взята тестова БД з 100k записами. Без всіляких оптимізацій запит з фронта в середньому виконувався за 2.3 секунд.

Додавання індексу до колонок дозволило скоротити запит до 2-х секунд, це не багато, але вже щось.
Ну тут все очевидно. Якщо юзер нічого не шукав, то замість порожньої строки передавався null і пошук не відбувався. Час виконання запиту скоротився з 2.3 до 1.3 секунди, якщо юзер щось фільтрує ‒ це +500мс, що цілком прийнятно.
Були видалені непотрібно джоіни які просто ніде не використовувалися.
TypeORM використовує active record pattern, який створює JSON-подібний об'єкт для роботи з БД. ORM-ки дуже сильно економлять час, але іноді генерують погані запити. Наприклад де можна було бахнути простий SQL запит, то TypeORM зробив два запити які зовсім не потрібні. Причина цього не відома, але автор стверджує, що це відома проблема. Ще до всього TypeORM також об'єднував чотири таблиці двічі по одному разу в обох запитах, а потім також сортував двічі по одному разу в обох запитах.
Саме ці два згенеровані запити були основною причиною проблеми, вони були замінені простим, а щонайголовніше ‒ одним SQL запитом:
SELECT
Submission.id,
Submission.language,
Submission.verdictCode,
...
FROM
submission AS Submission
LEFT JOIN problem ...
LEFT JOIN user ...
ORDER BY
Submission.created_at DESC
LIMIT 10
Коли був запущений новий запит, він виконувався всього за 100мс. Таким чином, ми скоротили запит з 1,3 секунди до 100мс, а в цілому з 2.3 секунди до 100мс. Що означає приріст продуктивності більш ніж в 23 рази!
Далі автор розповідає про інші способи оптимізації та дає рекомендації.
префікс%), індекс все ще може бути ефективно використаний. Однак, якщо шаблон знаходиться на початку (наприклад, LIKE %suffix), індекс не буде використано. У таких випадках варто розглянути можливість використання альтернативних методів, таких як повнотекстовий пошук.Отже! У фінальному результаті автору статті вдалося зменшити час очікування з 7 секунд до <=150 мс, що надзвичайно круто.
🌏 Оригінал: dev.to