Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Запрос тормозит когда он подзапрос 
:(
    Опции темы
maxipub
Дата 15.1.2019, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 517
Регистрация: 22.10.2009

Репутация: 1
Всего: 1



Добрый день.

Оптимизирую один код. Уже есть прогресс, но уперся в одном месте. Есть запрос на выборку товаров:

Код

SELECT some_data 
FROM goods AS g 
INNER JOIN cats AS c ON c.cat_id=g.cat_id 
INNER JOIN ( 
    SELECT DISTINCT i.goods_rev_id FROM items AS i 
    INNER JOIN stock_list AS l ON (l.stock_id=i.stock_id AND l.stock_avaliable=1) 
    WHERE i.order_id=0 ) AS n ON n.goods_rev_id=g.goods_id 
WHERE 
c.disabled=0 AND 
c.cat_id=123


goods - таблица с товарами
cats - разделы
items - наличие (одна строка - одна товарная позиция, нужно хранить индивидуальную информацию по каждой из них)
stock_list - список складов

Суть в том, что производится выборка данных по товарам указанного раздела (c.disabled=0 AND c.cat_id=123), которые есть в наличии (i.order_id=0) со всех доступных складов (l.stock_id=i.stock_id AND l.stock_avaliable=1).

Все это дело выполняется примерно 0,02 сек. Но дергается часто.

Сам по себе подзапрос возвращает список всех товаров в наличии со всех доступных складов. Он нужен для связи по конкретной ревизии товара.

Если подзапрос выполнить как самостоятельный запрос:

Код

SELECT DISTINCT i.goods_rev_id FROM items AS i 
INNER JOIN stock_list AS l ON (l.stock_id=i.stock_id AND l.stock_avaliable=1) 
WHERE i.order_id=0


То, он выполняется за 0,0004 сек и возвращает около 2500 записей - список id.

Но если сделать что-то вида:

Код

SELECT * FROM ( 
    SELECT DISTINCT i.goods_rev_id FROM items AS i 
    INNER JOIN stock_list AS l ON (l.stock_id=i.stock_id AND l.stock_avaliable=1) 
    WHERE i.order_id=0 ) AS t


То это тут же начинает выполнятся порядка 0,02 сек. Я так понимаю, именно подзапрос все дело тормозит. Индексы везде вылизаны, и используются. Само по себе подзапрос, как самостоятельный запрос, выполняется быстро, и выозвращает не много результатов. Но стоит поставить его в SELECT * FROM (-подзапрос-) AS t - как получаем эти пресловутые 0,02 сек...

Добавлено через 9 минут и 24 секунды
Если вдруг не очевидно для чего подзапрос - чтоб уменьшить пересечения при джойнах:

goods - десятки тысяч записей
cats - сотни
items - сотни тысяч
stock_list - десятки

И после этого придется накладывать на все группировку по товару...
PM MAIL   Вверх
Akina
Дата 15.1.2019, 16:04 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 453



Цитата(maxipub @  15.1.2019,  15:57 Найти цитируемый пост)
Если вдруг не очевидно для чего подзапрос - чтоб уменьшить пересечения при джойнах:

Не... всё становится хуже. Уж лучше "куча пересечений", но зато можно использовать индексы. А так ты получаешь неиндексированный результат подзапроса, который далее фуллсканится. Да ещё, не приведи господи, результат материализуется...


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxipub
Дата 16.1.2019, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 517
Регистрация: 22.10.2009

Репутация: 1
Всего: 1



Akina, MySQL 5.7.19, я слышал что начиная с 5.7 он умеет делать индексы для подзапросов, ошибся? EXPLAIN содержит какой-то auto_key0:

Код
1 PRIMARY <derived2> NULL ref <auto_key0> <auto_key0> 4 db.g.goods_id 10 100.00 Using where; Using index


А в общем все оказалось верно. Убрал подзапрос, сейчас все выполняется не дольше 0,0015 сек. Конечно, хотелось бы еще ускорить, но понимаю что места для маневров уже не много. Пока сойдет и так, позже еще попробую вернуться к этому вопросу.

В очередной раз большое спасибо!
PM MAIL   Вверх
Akina
Дата 16.1.2019, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 453



Цитата(maxipub @  16.1.2019,  12:26 Найти цитируемый пост)
я слышал что начиная с 5.7 он умеет делать индексы для подзапросов, ошибся? EXPLAIN содержит какой-то auto_key0

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

Цитата(maxipub @  16.1.2019,  12:26 Найти цитируемый пост)
хотелось бы еще ускорить

Не вижу потенции для ускорения, кроме создания подходящих индексов. Сплошные INNER JOIN и отборы по одному значению - нет пространства для манёвра.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.1009 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.