SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 23.10.2018 06:06:11

yakimov
Участник
Зарегистрирован: 27.12.2011
Сообщений: 9

Простой запрос c 3×JOIN + 1 млн данных = Using temporary :(

Всем привет!

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

Запрос


SELECT
    i.number,
    i.manufacturer_slug,
    m.name,
    m.madein,
    s.name,
    s.shipping_policy,
    s.payment_policy,
    s.return_policy,
    s.warehouse_location,
    MIN(p.price)
FROM item i
INNER JOIN price p ON p.manufacturer_slug = i.manufacturer_slug AND p.number = i.number
INNER JOIN shipper s ON s.slug = p.shipper_slug
INNER JOIN manufacturer m ON m.slug = i.manufacturer_slug
GROUP BY p.number, p.manufacturer_slug
ORDER BY null
 


EXPLAIN

Покрутить с данными можно на демо-сервере
ip: 159.69.206.58
port: 3306
user: demo
pass: demo

Права SELECT + INDEX.
Буду очень признаетелен за помощь и теоретическое объяснение работы MySQL. Т.к. хочется не просто решить проблему, а понять почему так smile

Отредактированно yakimov (23.10.2018 06:44:05)

Неактивен

 

#2 23.10.2018 06:39:44

yakimov
Участник
Зарегистрирован: 27.12.2011
Сообщений: 9

Re: Простой запрос c 3×JOIN + 1 млн данных = Using temporary :(

p.s. данные в таблицах связаны через slug (varchar). Не через id потому-что база обслуживается ручками через GUI клиента. Как только разработка ПО будет завершена, конечно же все будет переделано на id.

p.s.+ избыточные индексы добавлены в результате многократных экспериментов. Можно удалять...

p.s.++ данные используются в экспорте, поэтому получаемые 1 300 000 записей оправданы.

Отредактированно yakimov (23.10.2018 06:51:52)

Неактивен

 

#3 23.10.2018 11:57:35

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5516

Re: Простой запрос c 3×JOIN + 1 млн данных = Using temporary :(

yakimov написал:

p.s.+ избыточные индексы добавлены в результате многократных экспериментов. Можно удалять...

только прав на это нет
попробуйте добавить

alter table price add index(number, manufacturer_slug, price);

Неактивен

 

#4 23.10.2018 16:34:38

yakimov
Участник
Зарегистрирован: 27.12.2011
Сообщений: 9

Re: Простой запрос c 3×JOIN + 1 млн данных = Using temporary :(

vasya написал:

yakimov написал:

p.s.+ избыточные индексы добавлены в результате многократных экспериментов. Можно удалять...

только прав на это нет
попробуйте добавить

alter table price add index(number, manufacturer_slug, price);

Добавил, права добавил. Не помогло (

Неактивен

 

#5 23.10.2018 18:46:01

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5516

Re: Простой запрос c 3×JOIN + 1 млн данных = Using temporary :(

1. в shipper всего 4 записи, потому сервер предпочитает полный скан

2. можно явно задать порядок соединения таблиц
FROM price p
straight_join item i ON p.manufacturer_slug = i.manufacturer_slug AND p.number = i.number

Следующий вариант будет без Using temporary

explain SELECT
    i.number,
    i.manufacturer_slug,
    m.name,
    m.madein,
    s.name,
    s.shipping_policy,
    s.payment_policy,
    s.return_policy,
    s.warehouse_location,
    MIN(p.price)
FROM price p
straight_join item i ON p.manufacturer_slug = i.manufacturer_slug AND p.number = i.number
INNER JOIN shipper s force index (primary) ON s.slug = p.shipper_slug
INNER JOIN manufacturer m ON m.slug = i.manufacturer_slug
GROUP BY p.number, p.manufacturer_slug
ORDER BY null


3. Кажется, что таблица item запросе лишняя и его можно переписать как
explain SELECT
    p.number,
    p.manufacturer_slug,
    m.name,
    m.madein,
    s.name,
    s.shipping_policy,
    s.payment_policy,
    s.return_policy,
    s.warehouse_location,
    MIN(p.price)
FROM  price p
INNER JOIN shipper s force index (primary) ON s.slug = p.shipper_slug
INNER JOIN manufacturer m ON m.slug = p.manufacturer_slug
GROUP BY p.number, p.manufacturer_slug
ORDER BY null

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson