За последние 24 часа нас посетили 20663 программиста и 1113 роботов. Сейчас ищут 398 программистов ...

Вопрос про кеширование запросов к БД

Тема в разделе "PHP и базы данных", создана пользователем rolion, 24 сен 2019.

  1. rolion

    rolion Новичок

    С нами с:
    24 сен 2019
    Сообщения:
    4
    Симпатии:
    0
    VPS. Сайт. Серверная часть - PHP и MySQL. Есть поиск по сайту. После ввода 2-х символов идет запрос к БД и результаты сразу выгружаются под строку поиска. При вводе более 2-х символов - поиск сделал уже на стороне клиента из того, что пришло из БД, чтобы избежать лишних запросов.

    С клиентской частью все гуд, все по скорости устраивает. А вот запрос к БД не устраивает, около 2-х секунд - это долго, пользователь не будет набирать сначала два символа, потом подождал, потом остальные.

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

    Запросы стандартного вида:

    PHP:
    1. $resultCat = $mysqli->query("SELECT `id`,`title` FROM `cat` WHERE `title` LIKE '%".$query."%' ORDER BY `title`");
    Для связанных записей:

    PHP:
    1. $resultCityList = $mysqli->query("SELECT `id`,`title` FROM `city` ORDER BY `title`");// Вытаскиваем все города
    Затем, все это собирается в кучу и отдается AJAX-ом клиенту.

    Получается, что есть записи, которые можно кешировать на месяц, какие-то на сутки, какие-то на 15 минут, какие-то минут на 5.

    Как поступить лучше, посоветуйте пожалуйста:

    1) Кешировать как-то весь результат всех запросов для определенного значения $query. Т.е. если учесть что пользователь будет вводить на русском языке и это 2 символа, то думаю менее 1000 возможных результатов будет.

    2) Кешировать каждый запрос по отдельности с указанием срока.

    Ну и самый интересный вопрос: какое кеширование лучше здесь подойдет?

    Поможет ли MySQLCache, типа

    PHP:
    1. $resCity = $mysqli->query("SELECT SQL_CACHE `id`,`id_country`,`title` FROM `city` ORDER BY `title`");
    Или какое кеширование будет наиболее эффективным? Вообще этого не касался...
    Буду безмерно благодарен за советы и помощь!
     
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    Да тут бы индексировать чем-нибудь, если по разным таблицам
    --- Добавлено ---
    Ну и не вытаскивать все города, а делать join-ы
     
  3. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.816
    Симпатии:
    735
    Адрес:
    Татарстан
    + предыдущему оратору

    а так вы думаете о кешировании, не сделав элементарных вещей

    ну и все равно в строке подсказки вряд ли больше 10-20 элементов показываете, так сделайте в запросе LIMIT
     
  4. rolion

    rolion Новичок

    С нами с:
    24 сен 2019
    Сообщения:
    4
    Симпатии:
    0
    Это не подсказки, я таким образом выводить хочу все результаты. Человек ввел два символа, получил все ответы, вводя дальше поиск уже продолжается на клиенте.
    --- Добавлено ---
    Вытаскиваю 82 страны и 320 городов. Формирую массив.
    Затем, при выборке компаний, название которых удовлетворяет поиску, под названием подставляется страна и город.

    Разве вытащить отдельно и сформировать массив будет сильно медленнее, чем делать join при запросе компаний?
     
  5. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @rolion, спешу тебя расстроить LIKE это не для поиска по сайту. С ним вообще надо быть очень аккуратным, в идеале вообще забыть что он существует.
    Для поиска используй например Эластик, если это действительно поиск по сайту, а не по одному полю как у тебя.
    Ну или родной MySQL полнотекстовый на худой конец.
     
  6. rolion

    rolion Новичок

    С нами с:
    24 сен 2019
    Сообщения:
    4
    Симпатии:
    0
    Сможете подсказать по двум моментам:

    1) Если сравнивать скорость выполнения (не нагрузку на сервер) небольшой выборки из БД и складывания в массив стандартно, со скоростью выполнения подключения к Memchashed, проверкой на наличие и взятие оттуда если есть?
    Т.е. если сравнить скорость выполнения запроса к БД с городами (их там 320), затем перебираем строки и складываем в массив со скоростью взятия готового массива из Мемкешед если он там есть.
    Стоит или нет?

    2) Так как поиск у меня только по названиям компаний, товаров, категорий, подкатегорий и товарных групп, может не искать в каждой таблице при помощи %LIKE% вхождение подстроки из 3-х символов, а вытащить все названия по очереди, положить в один массив и закешировать при помощи Мемкешед. Затем, при обновлении или добавлении новой записи в БД кеш сбрасывать и перезаписывать. А поиск осуществлять перебором названий из этого массива и функцией, например stripos, смотреть, подходит ли нам строка или нет. Если подходит - оставляем и показываем пользователю, а если === false, то нет.
    Как считаете это будет быстрее чем 7 %LIKE% по таблицам в БД?
     
  7. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    1 однозначно да
    2 ты лет тридцать будешь городить городули и сделаешь жалкое подобие эластика, не проще ли взять готовое?
     
  8. rolion

    rolion Новичок

    С нами с:
    24 сен 2019
    Сообщения:
    4
    Симпатии:
    0
    )))
    Я просто нашел какую-то статью про работу эластика и его описание, показалось что городули будут проще. Какой-то тёмный лес. Может мне так показалось, не подскажете где примеры есть и почитать про эластик?

    И еще момент - насколько я понял при беглом осмотре, эластик хорош когда поиск идет по текстам статей, по большим объемам и т.д. А мне нужно найти вхождение всего 3-х символов в полях типа varchar до 100 символов. Общее количество строк для поиска на данный момент - 37 826. Хотя объём растет потихоньку.