Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите оптимизировать запрос / 15 сообщений из 15, страница 1 из 1
03.04.2014, 12:09:15
    #38604063
froosty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
Доброго времени суток. Есть такая задача:
Есть следующие таблицы:
category:
id,
parent_id,
title
...

filters:
id
title,
parent_id,
category_id
...

product:
id,
title,
category_id

product_filter:
id,
product_id,
filter_id

В двух словах: фильтры привязываются к категориям товаров. И друг к другу. Т.е. есть родительский фильтр (типа категории фильтров) и дочерние - фильтр, которые можно непосредственно задать для товара. В таблице product_filter соответственно связи между фильтрами и товарами.

Название товара состоит из названия производителя и модели. Т.е. например товар Italtherm City Basic 18 F. "Italtherm" - производитель, "City Basic 18 F" - модель. В таблице фильтров есть "категория фильтров" производитель, и для товара выбирается фильтр "производитель". Т.е. для данного примера в таблице фильтров будет категория фильтров "производитель", привязанная к категории товара и для неё дочерний фильтр "Italtherm", для которого в таблице product_filter будет связь с товаром.

Нужно организовать поиск по товарам следующим образом. Входные данные - некая строка символов". Нужно от исходного названия "Italtherm City Basic 18 F" отрезать название производителя, выбрав его из таблицы фильтров. Получится "City Basic 18 F". И уже по этому полю искать LIKEом. Сам я написал вот такой запрос:

Код: sql
1.
2.
3.
4.
5.
SELECT `product`.*
FROM `product`
left join `filters` on (`filters`.`parent_id` IN (SELECT `id` FROM `filters` WHERE `filters`.`category_id` = `product`.`category_id` AND lower(`filters`.`title`) = lower('производитель')) AND `filters`.`id` IN (SELECT `filter_id` FROM `product_filter` WHERE `product_id` = `product`.`id`))
WHERE LOWER(TRIM(' ' FROM SUBSTRING(`product`.`title`, (POSITION(`filters`.`title` IN `product`.`title`) + LENGTH(`filters`.`title`))))) LIKE LOWER('%18F%')
LIMIT 0, 10



Она работает медленно очень. Подскажите, можно ли как-то по-другому запрос написать, чтобы работало быстрее?

P.S. Просьба не отвечать в стиле "та тут структура хреновая. Надо было ...". Задача в том, чтобы с этой структурой сделать что-то человеческое.

Заранее спасибо за ответ =)
...
Рейтинг: 0 / 0
03.04.2014, 12:18:02
    #38604073
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
Просмотрел бегло...
1) Конструкцию IN (SELECT ...) переписывайте через JOIN или EXISTS. Да и вообще подзапрос в условии соединения - нужно очень хорошо понимать что делаешь, иначе велики шансы породить химеру.
2) LIMIT без ORDER BY - вам все равно, какие именно 10 строк будут в результате?
...
Рейтинг: 0 / 0
03.04.2014, 16:03:59
    #38604476
froosty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
miksoft,

Поменял IN (...) на join и exist... Заработало в 7 раз быстрее=) Спасибо огромное Вам за совет. Очень помогло

По ORDER BY - как не странно, но здесь действительно всё равно, какие конкретно 10 записей)

Ещё раз спасибо)
...
Рейтинг: 0 / 0
03.04.2014, 16:06:08
    #38604481
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
froostyПоменял IN (...) на join и exist... Заработало в 7 раз быстрее=) Спасибо огромное Вам за совет. Очень помоглоПоказывайте.
...
Рейтинг: 0 / 0
03.04.2014, 16:09:23
    #38604486
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
Она работает медленно очень. Подскажите, можно ли как-то по-другому запрос написать, чтобы работало быстрее?


МОЖНО!

P.S. Просьба не отвечать в стиле "та тут структура хреновая. Надо было ...".


Не отвечал.

Заранее спасибо за ответ =)


Да пожалуйста!
...
Рейтинг: 0 / 0
03.04.2014, 16:15:45
    #38604494
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
FROM `product` left join `filters` ...


Уже можно уржаться до колик.
А там ещё Limit.

Да, товарищь, тебе не бд надо советовать переделывать, тебе надо SQL учить сначала, потом только бд переделывать уже.
...
Рейтинг: 0 / 0
03.04.2014, 23:04:54
    #38604915
froosty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
miksoft,

Сделал так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT `p`.*
FROM `product` AS `p`
LEFT JOIN `filters` AS `par_t`
ON `par_t`.`category_id` = `p`.`category_id` AND lower(`par_t`.`title`) = lower('производитель')
LEFT JOIN `filters` AS `f_t`
ON (`f_t`.`parent_id` = `par_t`.`id` AND EXISTS(SELECT `filter_id` FROM `product_filter` WHERE `product_id` = `p`.`id` AND `filter_id` = `f_t`.`id`))
WHERE LOWER(TRIM(' ' FROM SUBSTRING(`p`.`title`, (POSITION(`f_t`.`title` IN `p`.`title`) + LENGTH(`f_t`.`title`))))) LIKE LOWER('RAS%')
LIMIT 0, 10



Смущает несколько то, что таблицу filters дважды присоединяю, но что-то я не могу придумать, как это изменить =(
...
Рейтинг: 0 / 0
03.04.2014, 23:10:05
    #38604925
froosty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
MasterZiv,

MasterZivFROM `product` left join `filters` ...


Уже можно уржаться до колик.
А там ещё Limit.

Да, товарищь, тебе не бд надо советовать переделывать, тебе надо SQL учить сначала, потом только бд переделывать уже.

Очень содержательно, а главное действительно мне помогло. А Вы наверное родились с безупречными знаниями всех технологий и Вам неведомо, что такое учиться.

Откровенно говоря, да, я на столько туп, что даже не понял, что Вас так рассмешило. Но хорошо, что мой вопрос подарил Вам смех. Я надеюсь, что Вам стало проще жить, ибо тогда Ваш ответ имел бы хоть какой-то смысл.
...
Рейтинг: 0 / 0
04.04.2014, 08:30:42
    #38605053
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
froosty,

Да слезы он подарил.
Left join тебе никогда ничего не отфильтрует. Он этого в принципе это не делает. Он только может множить записи.
И после этого ты ещё limit добавляешь, чтобы совсем не было видно, что же запрос отбирает.
...
Рейтинг: 0 / 0
04.04.2014, 08:44:51
    #38605061
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
MasterZiv,

Короче.

Запрос твой— бред сивой кобылы.
Переписанный запрос, я подозреваю, тоже, поскольку в изначальном запросе количество бреда зашкаливает.
Что он работает быстрее — случайность.
...
Рейтинг: 0 / 0
04.04.2014, 08:52:34
    #38605064
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
MasterZiv,

Сколько записей в таблице product?
До порядка 10 тысяч это ещё как то может будет работать, больше — просто умеет. Идея базовая дурацкая.
...
Рейтинг: 0 / 0
04.04.2014, 11:25:34
    #38605204
froosty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
MasterZiv,

На данный момент около 6000 записей.

Ну объясните, как делать так, чтобы было по человечески.

Сейчас изменил запрос, убрал LEFT JOIN, EXISTS, и сделал с помощью INNER JOIN. Работать стало ещё быстрее. В принципе, после последних исправлений, скорость работы запроса меня устраивает. Но на будущее, если не сложно, объясните, как нужно.
...
Рейтинг: 0 / 0
04.04.2014, 11:40:37
    #38605228
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
froostyРаботать стало ещё быстрее
Код: sql
1.
select rand() from dual

работает ещё быстрее; может, вам стОит использовать именно этот запрос? если всё дело только в скорости выполнения...
froostyНо на будущее, если не сложно, объясните, как нужно.froostyПросьба не отвечать в стиле "та тут структура хреновая. Надо было ...".Так вам шашечки надо или ехать? :)
...
Рейтинг: 0 / 0
04.04.2014, 12:16:03
    #38605279
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
froostyMasterZiv,

На данный момент около 6000 записей.

Ну объясните, как делать так, чтобы было по человечески.

Сейчас изменил запрос, убрал LEFT JOIN, EXISTS, и сделал с помощью INNER JOIN. Работать стало ещё быстрее. В принципе, после последних исправлений, скорость работы запроса меня устраивает. Но на будущее, если не сложно, объясните, как нужно.


Берем сухой остаток:



Нужно организовать поиск по товарам следующим образом. Входные данные - некая строка символов". Нужно от исходного названия "Italtherm City Basic 18 F" отрезать название производителя, выбрав его из таблицы фильтров. Получится "City Basic 18 F".


Название товара состоит из двух частей, которые хочется обрабатывать независимо. Так? А что это значит? А это значит, что тут налицо нарушение первой нормальной формы таблицы. И таки да, тебе придется переделывать твою бд, устранять эту аномалию.

Фильтры твои — просто пи3#@ц, какой чудак на другую букву их придумал — видимо, какой то старый матерый клипперист-dbf ник, больше 1000 записей в таблице никогда не видавший.
Это надо тоже выкидывать, заменять на просто тупо поиск по маске, заданной пользователем.

Ещё что может тебе помочь, это полнотекстовый поиск, причем он может даже без переделки бд. Но фильтры конечно все равно надо будет выбросить.
...
Рейтинг: 0 / 0
04.04.2014, 12:29:11
    #38605304
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать запрос
авторЕщё что может тебе помочь,
Сфинкс еще помочь может
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите оптимизировать запрос / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]