За последние 24 часа нас посетили 20133 программиста и 1282 робота. Сейчас ищут 677 программистов ...

Очень долгий поиск с использованием LIKE %$data%

Тема в разделе "MySQL", создана пользователем SBAlex, 12 авг 2023.

  1. SBAlex

    SBAlex Новичок

    С нами с:
    20 апр 2022
    Сообщения:
    26
    Симпатии:
    1
    Есть таблица куда пишется весь поступающий трафик. Вычленяются UTM-метки из GET-переменных и также записываются в таблицу как:

    utm1 - varchar(50)
    utm2 - varchar(50)
    utm3 - varchar(50)
    utm4 - varchar(50)
    utm5 - varchar(50)
    utm6 - varchar(50)
    utm7 - varchar(50)
    utm8 - varchar(50)

    Теперь я делаю поиск нужных мне UTM-меток, введя их частичные названия:
    SELECT * FROM traffic
    WHERE
    utm1 LIKE %$utm1% AND
    utm1 LIKE %$utm2% AND
    utm3 LIKE %$utm3%


    Пока таблица не заполнена, все выполняется быстро. Когда в ней становится около миллиона записей, даже при использовании пагинации тормоза просто дикие и ожидание нереально длительное. Индексы на эти поля проставлены.

    Возможно ли что-то сделать чтобы ускорить выборку. Может как-то запрос переделать, чтобы был более оптимальным.
     
  2. Drunkenmunky

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

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Вынести сами метки в отдельную таблицу. В таблице с трафиком хранить ID меток
     
  3. SBAlex

    SBAlex Новичок

    С нами с:
    20 апр 2022
    Сообщения:
    26
    Симпатии:
    1
    Так и сделал, это мне также пришло в голову. Вынес метки в отдельную таблицу utm. Но поиск все равно идет по текстовым значениям таблицы utm и это вызывает тормоза при большом объеме записей.
     
    #3 SBAlex, 12 авг 2023
    Последнее редактирование: 12 авг 2023
  4. Drunkenmunky

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

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Забавно. А если сначала найти все ID меток, и уже искать используя найденное?
     
  5. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    871
    Симпатии:
    135
    Разве нельзя избегать LIKE, перед записью разбирать метки и что-нить наворотить, да хоть доп. поля.
    И да, ТС, если тормозит сам фильтр, никакая пагинация его не спасёт.
     
  6. SBAlex

    SBAlex Новичок

    С нами с:
    20 апр 2022
    Сообщения:
    26
    Симпатии:
    1
    Приведу пример. У меня в основную таблицу, traffic при посещении сайта пишется запись об этом. UTM-метки я вынес в отдельную таблицу utm.

    Структура таблицы utm:

    id - int(10) unsigned autoincrement primary key
    utm1 - varchar(50)
    utm2 - varchar(50)
    utm3 - varchar(50)
    utm4 - varchar(50)
    utm5 - varchar(50)
    utm6 - varchar(50)
    utm7 - varchar(50)
    utm8 - varchar(50)

    Соотвественно, если на сайте +1 переход, то из УРЛа вычленяются ЮТМ метки и записываются новой записью в таблицу utm.

    Мне нужно бывает вывести количество кликов в случае если использовалась UTM "alpha". При этом очень часто приходится делать поиск по ЮТМ не зная ее полного названия, с использованием LIKE %ищем%. И вот тут начинаются дикие тормоза на больших объемах записей.
     
  7. Drunkenmunky

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

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Сколько записей в `utm`?
    И, кстати, зачем там восемь колонок?
     
  8. SBAlex

    SBAlex Новичок

    С нами с:
    20 апр 2022
    Сообщения:
    26
    Симпатии:
    1
    около 1500000. И это не предел.
    --- Добавлено ---
    Во входящем трафике используется до 8 UTM-меток. Под каждую метку одно поле.

    Проще ведь в одну запись в таблице 1 раз, одной командой добавить 8 меток, чем 8 раз сделать INSERT всех 8-ми ЮТМ меток в одно поле.

    p.s. Сорри если где туплю
     
  9. Drunkenmunky

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

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    ОК. Вернемся к началу.
    Заведите таблицу с метками, с двумя колонками. Если надо, то задайте уникальный индекс и на текстовое поле тоже.
    В таблице с трафиком поместите колонку с ID метки. Или даже восемь колонок, если их там до восьми
     
  10. SBAlex

    SBAlex Новичок

    С нами с:
    20 апр 2022
    Сообщения:
    26
    Симпатии:
    1
    Правильно ли я Вас понял, что стоит превратить таблицу utm в
    id - int(10) unsigned autoincrement primary key
    utm - varchar(50)

    и сделать индекс на поле utm.

    И этого должно хватить.
     
  11. Drunkenmunky

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

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Сначала поиск по `utm`(c %LIKE%), используя найденное составляется запрос к `traffic`
    Без %LIKE%. Только = или IN
    Если всё получится, то следующим шагом будет объединение таблицы traffic с результатами запроса к `utm`.
    Предыдущее предложение как бы упреждающее на возражения одного их присутствующих в топике пользователей
     
    #11 Drunkenmunky, 12 авг 2023
    Последнее редактирование: 12 авг 2023
  12. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    Добавлю только что выражение field LIKE '%str%', не может использовать индекс.
    Сильно подозреваю, что когда метки выделены в отдельную таблицу, то не надо ни 8 колонок, ни LIKE. А надо искать точное совпадение.