На сайте есть гибкий ajax поиск, можно слайдером настраивать цену, от какой до какой, искать по категориям, теги 20+, ещё несколько дополнительных параметров и, конечно, поиск по запросу.
Так назревает вопрос — как всё это дело оптимизировать? Сохранять каждый отдельный запрос в БД или кэшировать с помощью redis?
Параметров поиска много, пользователь поменяет всего один, и результат кардинально изменится. Дело даже не в том, что запросы сложные, нет, проблема заключается в частых обращениях к серверу.
Как решаются подобные проблемы в серьёзных проектах?
Как решаются подобные проблемы в серьёзных проектах?
Никак. Оптимизируют сам поиск, используя денормализацию данных что бы максимально упростить поиск и сделать его как можно менее напряжным для сервера. Ну и что бы "сократить" количество запросов используют "приемы" вроде throttle/debounce на клиенте, что бы не на каждый кник мышкой слать запрос, а когда пользователь не проявлял активности, к примеру секунду.
Частично эту проблему можно решить HTTP кешированием. То есть все парамеры поиска ходят в queryString а значит по одному URI мы можем иметь нужную страницу/данные. Однако вармат такого кэша будет занимать много времени, а сложность инвалидации будет так высока, что нужно 10 раз подумать прежде чем решаться на такое.
Немного дополню Сергея, т.к. его ответ правильный. Обычно используются NoSQL решения, вроде Solr, на котором реализуется фасеточный поиск. Вот самый простой пример такого https://lucidworks.com/blog/2009/09/02/faceted-sea...
Поиск делится на 2 вида: статический (поиск по чёткому совпадению) и динамический (поиск по нечёткому совпадению).
Выполняем в 2 этапа:
1. Сначала - выполняйте поиск по четкому совпадению, (int,boolean) =>
[список параметров: int,bool & etc.]=>ID:кэш1
2. Затем из этого списка - ищите по нечёткому (varchar). =>
varchar +ID:кэш1=>ID:кэш2
Теперь если текстовый поисковый запрос не менялся, а менялись только настройки - поиск выполняется через обратный реверсивный поиск и если такую комбинацию уже кто-то искал (она есть в кэше1), то результат будет практически моментально получен.
Можно сформировать клиентскую выборку (кэш-таблицу), исключив только что изменённый параметр из кэша1 (но сохранив строку поиска) и вынести результат выборки на клиент, чтобы в дальнейшем (если пользователь будет двигать "ползунок" цены, к примеру, не меняя поисковый запрос), искать уже локально на самом клиенте без запроса на сервер.