Какая логика этого запроса SQL ?

D
На сайте с 28.06.2008
Offline
1108
360

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

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

Сам запрос:

(SELECT 0 AS level, t1.*, CONCAT_WS('-', t1.id, t1.alias) AS item_alias, CONCAT_WS('-', t2.id, t2.alias) AS section_alias 
 FROM xyfq1_consultations_items AS t1 
 INNER JOIN xyfq1_consultations_sections AS t2 ON t1.section_id = t2.id 
 WHERE t1.parent_id = 0 AND t1.status = 1 AND t1.id != '1850' AND t1.section_id = '17' AND (t1.name LIKE '%Болезнь%' OR t1.name LIKE '%Паркинсона%')) 
 UNION (SELECT 1 AS level, t1.*, CONCAT_WS('-', t1.id, t1.alias) AS item_alias, CONCAT_WS('-', t2.id, t2.alias) AS section_alias 
        FROM xyfq1_consultations_items AS t1 
        INNER JOIN xyfq1_consultations_sections AS t2 ON t1.section_id = t2.id 
        WHERE t1.parent_id = 0 AND t1.status = 1 AND t1.id != '1850' AND t1.section_id = '17' AND t1.name NOT LIKE '%Болезнь%' AND t1.name NOT LIKE '%Паркинсона%') 
        ORDER BY RAND()  LIMIT 3

В функции, формирующей этот запрос такой код

        $words = preg_split('#[0-9\W_]+#u', $name, -1, PREG_SPLIT_NO_EMPTY);
        if (!empty($words)) {
            $sql = array();
            $sql2 = array();
            foreach ($words as $word) {
                            $sql[] = "t1.name LIKE ".$this->_db->quote('%'.$word.'%');
                              $sql2[] = "t1.name NOT LIKE ".$this->_db->quote('%'.$word.'%');

            }

Я так понимаю берется заголовок текущей консультации (какую страницу мы открыли), разбивается по словам и эти слова идут в запрос.

Что я не понимаю - зачем тут UNION ?

Т.е. первую часть запроса я понимаю - он ищет в этой же категории (t1.section_id = '17') консультации, в которых встречаются слова из названия текущей консультации, за исключением самой данной консультации (AND t1.id != '1850'), а далее идет UNION где эти же слова уже в NOT LIKE - ЗАЧЕМ?

ArbNet
На сайте с 27.10.2019
Offline
138
#1
Это где такую дичь откопал? 😁
Александр Мирту
На сайте с 12.09.2019
Offline
46
#2
Dram :

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

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

Сам запрос:

В функции, формирующей этот запрос такой код

Я так понимаю берется заголовок текущей консультации (какую страницу мы открыли), разбивается по словам и эти слова идут в запрос.

Что я не понимаю - зачем тут UNION ?

Т.е. первую часть запроса я понимаю - он ищет в этой же категории (t1.section_id = '17') консультации, в которых встречаются слова из названия текущей консультации, за исключением самой данной консультации (AND t1.id != '1850'), а далее идет UNION где эти же слова уже в NOT LIKE - ЗАЧЕМ?

Это попытка найти более точные результаты и поxожие

D
На сайте с 28.06.2008
Offline
1108
#3
Александр Мирту #:

Это попытка найти более точные результаты и поxожие

А в чем логика? Т.е. сначала ищем эти слова, а потом все что не содержит эти слова? Как это поможет повысить точность?

Александр Мирту
На сайте с 12.09.2019
Offline
46
#4
Dram #:

А в чем логика? Т.е. сначала ищем эти слова, а потом все что не содержит эти слова? Как это поможет повысить точность?

В целом, да, так и есть. Логика - дать больше результатов поиска, как вату, если изначальные запросы, к примеру, не дадут достаточный результат 

D
На сайте с 28.06.2008
Offline
1108
#5
Александр Мирту #:

В целом, да, так и есть. Логика - дать больше результатов поиска, как вату, если изначальные запросы, к примеру, не дадут достаточный результат 

Все теперь понятно, спасибо. Вероятно это было оправдано в начале, когда консультаций было мало, сейчас их десятки тысяч, уберу Юнион. 

S3
На сайте с 29.03.2012
Offline
342
#6
Интересный запрос, единственно - рандомная сортировка результатов может сильно выстрелить в ногу - скорость падает
W1
На сайте с 22.01.2021
Offline
306
#7
Dram :
далее идет UNION где эти же слова уже в NOT LIKE - ЗАЧЕМ?

Всё же написано: идёт разделение контента на две части - часть, которая содержит определённые слова, идёт в раздел level=0, а часть, которая не содержит этих слов, идёт в раздел level=1.

Dram #:
уберу Юнион

И потеряете  level=1. Зачем эта часть нужна - Вам виднее, это надо смотреть, что дальше происходит.

Мой форум - https://webinfo.guru –Там я всегда на связи
D
На сайте с 28.06.2008
Offline
1108
#8

Наверное в плане релевантности лучше использовать полнотекстовый индекс да? И искать нужно не кратком заголовке, а по всему вопросу.

Проверил - по скорости тоже самое что LIKE без Юнион  ~0.04 сек

(SELECT 0 AS level, t1.*, CONCAT_WS('-', t1.id, t1.alias) AS item_alias, CONCAT_WS('-', t2.id, t2.alias) AS section_alias 
  FROM xyfq1_consultations_items AS t1
  INNER JOIN xyfq1_consultations_sections AS t2 ON t1.section_id = t2.id
  WHERE t1.parent_id = 0 AND t1.status = 1
  AND t1.id != '1850'
  AND t1.section_id = '17' AND (MATCH(t1.text) AGAINST ('Болезнь') OR MATCH(t1.text) AGAINST ('Паркинсона')))  
ORDER BY RAND()  LIMIT 3
LEOnidUKG
На сайте с 25.11.2006
Offline
1762
#9

Скорость это отдельная тема, у тебя мог просто запрос закэшироваться или данных очень мало.

Если хочешь работать с поиском FULLINDEX, то НЕ совмещай в одном запросе выборку и FULLINDEX. БД, по сути, не умеет использовать одновременно два разных типа индексов и поэтому будет страдать скорость в больших масштабах.

Тут ИЛИ сначала делаем выборку по параметрам т.е. используем обычные индексы и уже в полученных данных ищем нужные слова, Или наоборот, ищем нужные слова и кромсаем уже из них.

Конечно можно хрен на это забить, но при масштабировании будет значительная потеря скорости. Но если масштабов не планируется, хотя бы на 2-3ГБ размер текстов, тогда можно и позабить 😊

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/ ✅ Настройка и оптимизация серверов https://getmanyspeed.ru/
W1
На сайте с 22.01.2021
Offline
306
#10
Александр Мирту #:
Это попытка найти более точные результаты и поxожие

Обоснуйте.

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий