Mysql Помогите с запросом - долго отрабатывает

Benderlio

Новичок
Запрос такой
Код:
SELECT SQL_NO_CACHE id_shop , web, city_name, city_2_name, region_name, city_eng, name, city_id, `e-mail`, pay,phone , `time`, tc, adres, logo,network
FROM i_cat_2_shop
join shop on (i_cat_2_shop.shop_id=shop.id_shop)
join city on (shop.city=city.city_id)
join region using (region_id)
join i_cat using (i_cat_id)
where
i_cat_biz=0 and shop.state=1
group by i_cat_2_shop.shop_id
order by i_cat_2_shop.shop_id DESC limit 0,10
Эксплейн
ex.gif

в таблице i_cat_2_shop по полям i_cat_id и shop_id сделаны уникальными
Отрабатывает 10 секунд, если убираю ордеры и группировку то 0.01

Подскажите, пожалуйста, как ускорить если возможно.
 
Последнее редактирование модератором:

Фанат

oncle terrible
Команда форума
Во-первых, максимально упрости запрос. Выкини все джойны, которые не влияют на работу. Сделай запрос только к i_cat_2_shop и работай с ним.
Во-вторых, зачем здесь группировка вообще?
В-третьих, сортировка по убыванию всегда файлсорт - индекс-то расположен по возрастанию.
 
Последнее редактирование:

Benderlio

Новичок
Фанат, группировка т.к. таблица i_cat_2_shop это "многие ко многим", вообщем один магазин на несколько рубрик. В выводе необходимы уникальные магазины. Могу выкинуть только таблицы city и region - но на время они не влияют
 

Gas

может по одной?
i_cat_biz=0 - это условие по какой таблице?
join i_cat using (i_cat_id) - c какой таблицей джойнится i_cat ?
у всех шопов в обязательном порядке есть city ?

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

группировка т.к. таблица i_cat_2_shop это "многие ко многим"
а зачем её джойнить в данном запросе и соответственно делать группировку? условий по ней я не вижу
 

Benderlio

Новичок
Gas, i_cat_biz=0 - это условие по какой таблице? это условие по таблице i_cat
join i_cat using (i_cat_id) - c какой таблицей джойнится i_cat ? джойнится с таблицей i_cat_2_shop
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Охохох...
"Не ДАМ я Некту два яблока, хоть он дерись!!!!11111"

Я тебе не предлагаю выкинуть таблицы совсем. Это надо для того, чтобы не путаться с бесполезными джойнами, пока оптимизируешь основной косяк. Так доступно?
У тебя 200к строк перебираются в таблице i_cat_2_shop. ВОТ ЭТОТ ЗАПРОС И НАДО ОПТИМИЗИРОВАТЬ
а после того как закончишь - вешать на неё джойны обратно.

Окей, i_cat_2_shop - многие ко многим. Как это отражается на этом конкретном запросе?
Какое поле берется из i_cat?
 

Benderlio

Новичок
i_cat_2_shop - связь магазина с категорией
i_cat - категории в которых есть категории которые не относятся к магазинам - услуги, т.е. из i_cat выбираем поле
i_cat_biz=0 т.е. выбираем только магазины

т.е. тут мне просто необходимо добраться джойнами до таблицы i_cat в которой хранится тип категории (магазин или нет) и уже исходя из этого через таблицу связи категории и магазина i_cat_2_shop выбрать только магазины

как то так

выкинул то что не нужно

SELECT SQL_NO_CACHE id_shop , web, name, `e-mail`, pay,phone , `time`, tc, adres, logo,network
FROM shop
join i_cat_2_shop on (i_cat_2_shop.shop_id=shop.id_shop)
join i_cat using (i_cat_id)
where
i_cat_biz=0
and shop.state=1
group by shop.id_shop
order by shop.id_shop DESC
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Господи, ну до чего же люди непонятливые.

select shop_id from i_cat_2_shop group by id_shop

даст тебе ТУ ЖЕ САМУЮ картину на експлейне. И вот его и надо оптимизировать. ОДИН.

условию i_cat_biz=0 AND id_shop = 1 сколько записей в from i_cat_2_shop соответствует и почему?

Спрашиваю я затем, что оптимизировать групбаи - дело муторное.
И лучше обойтись без него. И пока непонятно, нафига он в запросе вообще.
 

Benderlio

Новичок
условию i_cat_biz=0 AND id_shop = 1 сколько записей в from i_cat_2_shop соответствует и почему?

будет соответствовать 4 записи т.к. магазин 1 находится в 4 категориях, а поле i_cat_biz=0 указывает что он магазин и находится(это поле) в таблице i_cat (таблице категорий магазинов)

ex1.gif
 

Фанат

oncle terrible
Команда форума
погоди. но ведь у трех из четырех категорий i_cat_biz не равно нулю? То есть в итоге строчка все равно вернется только одна?
 

Фанат

oncle terrible
Команда форума
Короче, мне в лом разбираться в этой структуре.
Я уверен что группировка здесь нафиг не нужна, а структура таблиц передизайнена.

Если так хочется групбай- вперед и с песней индекс по shop_id, i_cat_id
и смотреть - поможет ли
и убрать сортировку
 

Benderlio

Новичок
спасибо, разбил на 2 запроса вроде значительно быстрее стало хотя все равно не очень.

Фанат, ну почему же передизайнена
таблицы такие
магазины, категории и таблица связи магазинов с категориями

я и схему нарисовал http://dbdsgnr.appspot.com/app#agdkYmRzZ25ycg8LEgZTY2hlbWEYytP9Agw
 

riff

Новичок
Попробуй
Код:
SELECT ... FROM shop
left join i_cat_2_shop on (shop.id_shop = i_cat_2_shop.shop_id)
left join i_cat on (...соединяем c i_cat2shop... AND i_cat_biz=0)
left join city on (shop.city=city.city_id)
where
shop.state=1
order by shop.id_shop DESC limit 0,10
 
Последнее редактирование:

Benderlio

Новичок
в итоге остановился на этом
SELECT shop_id
FROM `i_cat_2_shop`
join i_cat using (i_cat_id)
join shop on (i_cat_2_shop.shop_id=shop.id_shop)
where i_cat.i_cat_biz=0
and state=1
group by shop_id
order by shop.pay DESC,shop_id DESC

получаю список айдишек и уже потом по ним делаю запрос для данных, так получается значительно быстрее
 

riff

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

Benderlio

Новичок
riff, да вот теперь надо замерять время между вашим вариантом и тем что за 2 запроса
 

Фанат

oncle terrible
Команда форума
Вот и я о том же.
А ты просто забыл SQL_NO_CACHE.

волшебства не бывает.
Если у тебя тормозило из-за перебора 200к записей, то убирание одного джойна, который цепляет 20 записей, ничего как бы не изменит.

последние две сторки, как ты мог заметить, выбирают ровно по ОДНОЙ записи, и погоды никакой абсолютно не делают.
 
Сверху