Skip to Content

Пошук по 110 000 товарів займав вісім секунд. Тепер - одну.

Чому лікування було не в більшому сервері і в що обійшлася експлуатація.
11 вересня 2026 р. від
odoo-dev.org

У магазину на Odoo з каталогом більш ніж сто тисяч позицій зʼявляється проблема, якої ніколи не видно на демо-базі: пошук перестає бути миттєвим. У нас він займав вісім–десять секунд із увімкненими фільтрами. Чекав склад, чекали продавці, і всі звикли відкривати другу вкладку, поки думає перша.

Час пошуку до і після: вісім–десять секунд проти менше секунди
Цифра, яка мала значення для тих, хто працює в системі.

Що саме було повільним

Перше бажання - звинуватити сервер, і воно майже завжди хибне. Памʼяті вистачало, диски не були завантажені. Час ішов в один запит, і план запиту пояснював чому.

Пошук по каталогу - це не одне питання, а кілька одразу: знайти рядки, у тексті яких є фрагмент, звузити їх за кількома атрибутами і порахувати, скільки товарів лишилося за кожним значенням фільтра, щоб числа біля галочок не брехали. На кількох тисячах товарів це безкоштовно. На ста десяти тисячах рядків із довгими описами й кількома приєднаними таблицями атрибутів база змушена перебирати майже все - на кожне натискання клавіші і на кожного відвідувача.

Індекси тут не рятують. Пошук за фрагментом усередині слова звичайним індексом скористатися не може в принципі, а лічильники фільтрів перераховуються заново на кожен запит за визначенням: вони залежать від того, що відвідувач уже обрав.

І каталог був на тій машині не один. Та сама Odoo обслуговувала ще тридцять девʼять вітрин зі спільного пулу воркерів, тож кожен повільний пошук забирав воркер одразу в усіх.

Спершу виміряти

Що робити далі, вирішують два числа: скільки часу йде в бази на запит і скільки в браузера на все інше. Якби відповідь була в браузері, ми б тиждень оптимізували не ту половину системи.

Браузер був ні до чого. Лог повільних запитів і план запиту вказували на те саме місце, і це зробило рішення простим.

Що змінилося

Пошук переїхав із бази в Elasticsearch, який тримає власний індекс і створений саме під це питання: текст, фільтри й лічильники одночасно. Поле пошуку на сайті лишилося там само, і людина, яка в ньому друкує, не бачить нічого нового - крім того, що результати вже тут.

Odoo питає сервіс на Go, той іде в Elasticsearch і Redis
Odoo лишається єдиним місцем, куди пишуть дані.

Важливий тут бік стрілки. Odoo лишається джерелом істини: товари, ціни й залишки живуть і правляться там. Індекс збирається з бази і перезбирається при зміні записів - і ніколи навпаки. Якщо індекс загубиться, його можна викинути й побудувати заново: нічого цінного в ньому не зберігається.

110 000+товарів у каталозі
8–10 сфасетний пошук до
менше 1 стой самий пошук після

З чого це зібрано

Нічого тут не писалося з нуля заради самого процесу. Модуль для Elasticsearch куплений і перероблений, а поверх нього - міст до теми магазину, щоб поле пошуку, сторінка каталогу й фільтри розмовляли з індексом, а не з базою.

Між Odoo і сховищами стоїть невеликий сервіс на Go. Він збирає запит із фільтрами, питає Elasticsearch, рахує лічильники фасетів і тримає важкі шматки сторінки товару в Redis із таймаутом у десятки мілісекунд - якщо не відповів вчасно, на нього ніхто не чекає.

Навіщо взагалі окремий сервіс: на хостингу Odoo поруч із нею власний демон не підняти, туди немає доступу. Тому сервіс живе зовні і відповідає по HTTP. На власному сервері він переїжджає в ту саму підмережу, і цей перехід майже нічого не коштує.

І магазин працює далі, коли сервіс не працює. Та сама логіка фільтрації є в Odoo на чистому Python: повільніше, але правильно. Цей шлях не рудимент - саме через нього викатка сервісу перестала бути подією, яку треба планувати.

У що це обходиться

Чесна відповідь включає ціну, і це не лише робота з перенесення пошуку. Зʼявився другий сервіс, який треба запускати, моніторити й бекапити. Його індекс потрібно перезбирати після масових імпортів. Хтось має помічати, коли він відстав, і система має поводитися розумно в ту хвилину, коли він недоступний.

Це і є справжній обмін: постійний шматок інфраструктури навзамін пошуку, який більше не змушує людей чекати. Для каталогу такого розміру обмін очевидно вигідний. Для каталогу на пʼять тисяч позицій - зазвичай ні.

Коли все це не потрібно

Якщо пошук повільний на невеликому каталозі, причина майже ніколи не в обсязі даних. Частіше це запит, який приєднує зайве, відсутній індекс на полі, за яким фільтрують на кожній сторінці, картинка, що блокує відмальовування, або сніпет, який перемальовує весь список на кожне натискання клавіші. Це коштує дня роботи, а не нового сервісу в продакшені.

Тому перший крок завжди той самий: спершу виміряти, потім міняти. Вимірювання займає годину і економить тиждень, витрачений на оптимізацію не тієї половини.

Ще обираєте саму систему? Тоді арифметика йде раніше за архітектуру: у що обходиться команда з десяти осіб в Odoo, Salesforce, HubSpot і SAP.

Цікаво, як ті самі системи поводяться щодня? Odoo в експлуатації: що тримає, що ламається, чого немає в документації.

Партнер Odoo чи незалежний розробник: у чому різниця насправді
З чого складаються рівні Ready, Silver і Gold та кому платять, коли ви купуєте більше місць.