Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Помогите оптимизировать SQL запрос
LEFTJOIN items_cats AS cat ON cat.itemID = item.id
WHERE cat.catID = 1
ORDERBY item.name ASCLIMIT 0,30;
Мелкий
Отправлено: 13 Сентября, 2016 - 11:29:31
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
explain где? Какая СУБД?
NeuroZ пишет:
LEFT JOIN items_cats AS cat ON cat.itemID = item.id
WHERE cat.catID = 1
Логическая ошибка. Делаете inner join, а написано left join. Может сбивать с толку оптимизатор.
На мой взгляд пользователя выводить на страницу категории произведение цен на склады как-то странно. Да и, кажется, это слабо совпадает с реальностью. На каждом складе есть каждая цена? Зачем тогда знать про склады? Надо тогда знать про сумму всего. Или там 1:1 связь? Зачем тогда отдельные таблицы?
И по общему дизайну в 3 из 4 таблицах поле id нафиг не нужно. Если, правда только, это не обязывает делать какая-нибудь глупая orm.
И ещё взгляд пользователя - товары без цен реально надо выводить в каталоге?
----- PostgreSQL DBA
NeuroZ
Отправлено: 13 Сентября, 2016 - 12:13:50
Посетитель
Покинул форум
Сообщений всего: 393
Дата рег-ции: Апр. 2012
Помог: 2 раз(а)
Мелкий пишет:
Логическая ошибка. Делаете inner join, а написано left join. Может сбивать с толку оптимизатор.
На мой взгляд пользователя выводить на страницу категории произведение цен на склады как-то странно. Да и, кажется, это слабо совпадает с реальностью. На каждом складе есть каждая цена? Зачем тогда знать про склады? Надо тогда знать про сумму всего. Или там 1:1 связь? Зачем тогда отдельные таблицы?
И по общему дизайну в 3 из 4 таблицах поле id нафиг не нужно. Если, правда только, это не обязывает делать какая-нибудь глупая orm.
И ещё взгляд пользователя - товары без цен реально надо выводить в каталоге?
1. Заменил всё на INNER JOIN (уменьшилось время до 26 секунд)
2. Фактически в складах хранится кол-во конкретного товара и минимальная единица заказа
3. Технически таблицу склада и цен можно объединить в одну (разделены они только из соображения логики, именно поэтому отдельные таблицы)
4. По поводу того, что не нужно поле id в 3 из 4 таблицах - согласен. По привычке поставил примари кей с автоинкрементом.
5. "Товары без цен в каталоге?" - наоборот как раз.. Цены и кол-во товаров нужны на странице списка товаров.
В виду особенностей данных и дизайна сайта - отсутствует страница "карточка товара". Т.е. пользователь может добавить товар в корзину прямо со страницы списка товаров.
Так как тогда лучше сделать?
-Объединить таблицу склада и цен? (по замерам выигрываем в скорости, снижая ее до 7 секунд)
-Какие еще действия можно произвести?
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
NeuroZ пишет:
1. Заменил всё на INNER JOIN (уменьшилось время до 26 секунд)
NeuroZ пишет:
5. "Товары без цен в каталоге?" - наоборот как раз.. Цены и кол-во товаров нужны на странице списка товаров.
Это вопросы к задаче и осмысленности использования inner или left join.
Если цены товара в таблице цен нет - этот товар в случае left join всё равно будет выведен. Аналогично в случае склада. Это может быть ожидаемым поведением.
NeuroZ пишет:
2. Фактически в складах хранится кол-во конкретного товара и минимальная единица заказа
3. Технически таблицу склада и цен можно объединить в одну (разделены они только из соображения логики, именно поэтому отдельные таблицы)
Не пониманию требований и ограничений вашей предметной области. Но перемножать цены на склады мне по-прежнему кажется странной идеей, почему 5 складов и 3 цены должны выводиться как 15 позиций в каталоге?
NeuroZ пишет:
В виду особенностей данных и дизайна сайта - отсутствует страница "карточка товара". Т.е. пользователь может добавить товар в корзину прямо со страницы списка товаров.
Всё равно с точки зрения пользователя мне не нравится куча идентичных предложений. А у вас они элементарно группируются и лишь искусственно множатся в интерфейсе. Пример интерфейса: описание товара, минимакс цен, информацию о количестве, хинт с расшифровкой где и по какой цене доступно. Над кнопкой заказа подумать. Можно модальным окном, можно slidedown с таблицей склад-цена-количество-купить (короткие списки можно и сразу держать открытыми).
Ещё раз, explain где? И какая СУБД? Хотя limit, offset через запятую - вроде бы только mysql. Но не претендую на знание всех диалектов, может и что-то другое ещё есть.
----- PostgreSQL DBA
NeuroZ
Отправлено: 14 Сентября, 2016 - 09:50:36
Посетитель
Покинул форум
Сообщений всего: 393
Дата рег-ции: Апр. 2012
Помог: 2 раз(а)
Мелкий пишет:
Это вопросы к задаче и осмысленности использования inner или left join.
Если цены товара в таблице цен нет - этот товар в случае left join всё равно будет выведен. Аналогично в случае склада. Это может быть ожидаемым поведением.
Да, да, я понял в чем суть этих запросов. И Вы правы, мне именно INNER JOIN нужен.
Мелкий пишет:
Не пониманию требований и ограничений вашей предметной области. Но перемножать цены на склады мне по-прежнему кажется странной идеей, почему 5 складов и 3 цены должны выводиться как 15 позиций в каталоге?
В каком месте у меня происходит перемножение?
Мелкий пишет:
Ещё раз, explain где? И какая СУБД? Хотя limit, offset через запятую - вроде бы только mysql. Но не претендую на знание всех диалектов, может и что-то другое ещё есть.
1 SIMPLE item ALL PRIMARY 14047 Using filesort
1 SIMPLE pr eq_ref PRIMARY PRIMARY 4 autosite.item.id 1
1 SIMPLE cat eq_ref PRIMARY PRIMARY 4 autosite.item.id 1 Using where
Объединил 2 таблицы (цен и склада), убрал лишние колонки id. Получил время выполнения 0.061s (вполне удовлетворительно).
Текущий SQL практически не изменился (убрана 1 таблица из запроса)
Понятно, почему в результате 8 строк, из которых 6 про item = 1?
----- PostgreSQL DBA
NeuroZ
Отправлено: 14 Сентября, 2016 - 11:56:55
Посетитель
Покинул форум
Сообщений всего: 393
Дата рег-ции: Апр. 2012
Помог: 2 раз(а)
Всё, я понял... так действительно получается перемножение (в общем случае).
Просто в моем, частном, случае всегда 1 цена на 1 товар и 1 склад на 1 товар, поэтому я и не видел явного перемножения.
А так, конечно бы перемножалось и было бы вообще не очень) (Добавление)
Обязательно буду учитывать все эти моменты когда буду писать универсальную систему e-commerce
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.