Перейти к публикации
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...

Вибір товарів, в яких залишок по опціях = 0


remix8080
 Поделиться

Рекомендованные сообщения

Вітаю.

Спекотно, підтуплюю (

Допоможіть, будь ласка, скласти запит по вибірці з таблиці oc_product всіх product_id, для яких в oc_product_option_value залишок всіх опцій рівний 0 (quantity=0).

Наперед дякую!

Ссылка на комментарий
Поделиться на других сайтах


Пробую так (поки з таблиці oc_product_option_value):

SELECT prov.product_id, prov.quantity FROM oc_product_option_value prov GROUP BY prov.product_id, prov.quantity HAVING MAX(prov.quantity)=0 ORDER BY 1

але попадаються товари, в яких є ненульові залишки опцій (

Изменено пользователем remix8080
Ссылка на комментарий
Поделиться на других сайтах


Вітаю.
Допоможіть, будь ласка, прискорити запит.
Потрібно в таблиці oc_product обнулити залишки товарів, для яких залишок опцій рівний 0.
При кількості записів ~15К в oc_product і ~3,5К в oc_product_option_value запит

UPDATE `oc_product` pr SET pr.quantity=0 WHERE pr.product_id IN 
(SELECT prov.product_id FROM `oc_product_option_value` prov GROUP BY prov.product_id HAVING MAX(prov.quantity)=0);

виконується кілька хвилин - якось нефеншуйно (

Ссылка на комментарий
Поделиться на других сайтах


Специ, підкажіть, як можна оптимізувати/прискорити цей запит? Виконується більше 3 хв (

UPDATE `oc_product` pr SET pr.quantity=0 WHERE pr.product_id IN 
(SELECT prov.product_id FROM `oc_product_option_value` prov GROUP BY prov.product_id HAVING MAX(prov.quantity)=0);

Сам селект

SELECT prov.product_id FROM `oc_product_option_value` prov GROUP BY prov.product_id HAVING MAX(prov.quantity)=0

виконується практично миттєво.

Ссылка на комментарий
Поделиться на других сайтах




Такий запит буде швидше, (при наймні в данному випадку):
 

SELECT DISTINCT prov.product_id FROM `oc_product_option_value` prov WHERE `quantity` = 0

аніж Ваш 

 

SELECT prov.product_id FROM `oc_product_option_value` prov GROUP BY prov.product_id HAVING MAX(prov.quantity)=0

 

А час виконання апдейту залежіть, мені здається, від того, яку кількість product_id повертає попередній запит.

Тому в UPDATE краще зменьшити кількість апдейтів, додавши в запит перевірку на кількість.

UPDATE `oc_product` pr SET pr.quantity=0 WHERE pr.quantity > 0  AND pr.product_id IN 
(SELECT DISTINCT prov.product_id FROM `oc_product_option_value` prov WHERE `quantity` = 0);

Таким чином не будуть апдейтітись поля, в яких ВЖЕ кількість дорівнює 0.

  • +1 1
Ссылка на комментарий
Поделиться на других сайтах

03.07.2022 в 01:02, nogocuHoBuk сказал:



Такий запит буде швидше, (при наймні в данному випадку):
 

SELECT DISTINCT prov.product_id FROM `oc_product_option_value` prov WHERE `quantity` = 0

аніж Ваш 

 

Не варіант. Цей видасть товари, в яких ХОЧА Б ОДНА опція має залишок 0. А я вибираю ВСІ такі товари. Та й швидість цього запиту практично не береться до уваги. Результат видає не багато, ~ 200 товарів.

 

 

 

03.07.2022 в 01:02, nogocuHoBuk сказал:

Тому в UPDATE краще зменьшити кількість апдейтів, додавши в запит перевірку на кількість.

UPDATE `oc_product` pr SET pr.quantity=0 WHERE pr.quantity > 0  AND pr.product_id IN 
(SELECT DISTINCT prov.product_id FROM `oc_product_option_value` prov WHERE `quantity` = 0);

Таким чином не будуть апдейтітись поля, в яких ВЖЕ кількість дорівнює 0.

Перевірку не додавав, думав, не дасть приросту. Але все-таки при pr.quantity>0 зменшився час з 210с до 160с. Вже результат )

 

П.С. Вдячний за відповідь.

Ссылка на комментарий
Поделиться на других сайтах


03.07.2022 в 01:41, remix8080 сказал:

А я вибираю ВСІ такі товари.

Так. То вже я тупанув.
 

 

03.07.2022 в 01:41, remix8080 сказал:

Перевірку не додавав, думав, не дасть приросту. Але все-таки при pr.quantity>0 зменшився час з 210с до 160с. Вже результат )

При повторному запиті має зрости до 0. (звісно залежить від часу виконання SELECT'а)
Тому краще повісити на крон раз в день/12 годин/годину в залежності від кількості продаж. Може раз на день, а може й раз на годину :) При періодичному виконанні кількість апдейтів буде стабільно мала.

Ссылка на комментарий
Поделиться на других сайтах

Всі наступні запити також виконуються такий самий час (~160с).

П.С. Саме на крон і планую згодом повісити деякий "пучок" запитів.

Ссылка на комментарий
Поделиться на других сайтах


03.07.2022 в 01:54, remix8080 сказал:

такий самий час (~160с).

додайте oc_product_quantity до индексу
 

ALTER TABLE `oc_product` ADD INDEX(`quantity`)


І насолоджуйтесь :) 
Бо перший запит апдейта до кількості. Дайте змогу вибрати значення миттєво (в переносному сенсі, звісно). 
Навіть при 15к записів навіть 160 секунд це ДУЖЕ багато.

 

Ссылка на комментарий
Поделиться на других сайтах

03.07.2022 в 02:07, remix8080 сказал:

Індекс додав. Час не змінився.

Це все "Stranger Things"

Ссылка на комментарий
Поделиться на других сайтах

Знайшов рішення
 

UPDATE `oc_product` pr SET pr.quantity=0 WHERE pr.product_id IN 
	(
	SELECT prod_id FROM 
			(
			SELECT prov.product_id AS prod_id FROM `oc_product_option_value` prov 
			LEFT JOIN oc_product op 
			ON op.product_id = prov.product_id 
			WHERE op.quantity > 0 
			GROUP BY prov.product_id HAVING MAX(prov.quantity)=0
			) 
	AS pid
	)

Задля наочності написав у кілька рядків.
Суть полягає в тому, що SELECT вибирає лише ті product_id для IN, де кількіть в oc_product більше 0
Ну і таке рішення само по собі буде швидше.

Ваше перше рішення: 1.37 секунд
 

Скрытый текст

image.thumb.png.679ef93aeffdf77c7028ff21e2632abc.png


Мій перший варіант, з додаванням перевірки кількості: 0.79 секунд
 

Скрытый текст

image.thumb.png.43563acc05b98b8f41f30dc78689c6e9.png


Остаточне рішення: 0.05 секунд
 

Скрытый текст

image.png.184da743d800746ece6c6e6079b60f87.png


Нарешті можу і в люлю)

  • +1 1
Ссылка на комментарий
Поделиться на других сайтах

03.07.2022 в 02:53, nogocuHoBuk сказал:

Знайшов рішення
 

UPDATE `oc_product` pr SET pr.quantity=0 WHERE pr.product_id IN 
	(
	SELECT prod_id FROM 
			(
			SELECT prov.product_id AS prod_id FROM `oc_product_option_value` prov 
			LEFT JOIN oc_product op 
			ON op.product_id = prov.product_id 
			WHERE op.quantity > 0 
			GROUP BY prov.product_id HAVING MAX(prov.quantity)=0
			) 
	AS pid
	)

 

 

Брр, не знаю як, але відпрацювало практично моментально. Розбиратися/аналізувати вже буду завтра )

 

03.07.2022 в 02:53, nogocuHoBuk сказал:

Нарешті можу і в люлю)

Як в Петрика П'яточкіна. "Ура, 10 слоненят. Тепер я засну" )))

Ссылка на комментарий
Поделиться на других сайтах


03.07.2022 в 03:07, chukcha сказал:

откажитесь от IN
Используйте JOIN

 

Пробував, експериментував - не вийшло (

Ссылка на комментарий
Поделиться на других сайтах


03.07.2022 в 03:36, remix8080 сказал:

Пробував, експериментував - не вийшло (

покажіть спробу

Ссылка на комментарий
Поделиться на других сайтах

Доброго дня.

03.07.2022 в 10:37, chukcha сказал:

покажіть спробу

Якось так

UPDATE oc_product pr
INNER JOIN (SELECT prov.product_id FROM `oc_product_option_value` prov GROUP BY prov.product_id HAVING MAX(prov.quantity)=0)
ON pr.product_id = prov.product_id
SET pr.quantity = 0

 

Ссылка на комментарий
Поделиться на других сайтах


меня смущает
MAX
Зачем он вам если вам нужны опции с quantity 0

Ссылка на комментарий
Поделиться на других сайтах

Для одного товару з oc_product може бути кілька записів в oc_product_option_value, серед яких не всі quantity=0. Тому через MAX вибираю всі нульові.

Ссылка на комментарий
Поделиться на других сайтах


03.07.2022 в 16:50, remix8080 сказал:

Тому через MAX вибираю всі нульові.

Мені здається (я навіть впевнений) що SUM() буде працювати швидше, ніж MAX()

SUM(prov.quantity)=0

 

Ссылка на комментарий
Поделиться на других сайтах

Думаю, не істотно, оскільки запит з MAX виконується практично моментально.

UPD. При великій кількості записів в oc_product_option_value - безперечно.

Изменено пользователем remix8080
Ссылка на комментарий
Поделиться на других сайтах


03.07.2022 в 16:53, remix8080 сказал:

Думаю, не істотно

КРщае перевірити
 

SELECT prov.product_id FROM `oc_product_option_value` prov GROUP BY prov.product_id HAVING MAX(prov.quantity)=0

а потім 
 

SELECT prov.product_id FROM `oc_product_option_value` prov GROUP BY prov.product_id HAVING SUM(prov.quantity)=0


Бо на моїх 100 записах час в межах похибки
У Вас точніше буде. 

Ссылка на комментарий
Поделиться на других сайтах

03.07.2022 в 15:16, remix8080 сказал:

Якось так

Доречі. У Вас тут має бідкатися БД на те, що немає аліасів.
Потрібно якось так:

UPDATE oc_product pr
INNER JOIN (SELECT prov.product_id FROM `oc_product_option_value` prov GROUP BY prov.product_id HAVING MAX(prov.quantity)=0) AS per
ON pr.product_id = per.product_id
SET pr.quantity = 0
WHERE pr.quantity > 0

(додав ще й перевірку на кількість більше 0)
Але мені здається цей запит будет довшим за той, що я пропонував раніше.
Бо там для IN вибираються виключно ті product_id у яких кількість в oc_product більше 0.

В останньому ж запиті кількість записів для обробки значно більша.
PS. Ну і в такому вигляді потестуйте чи є різниця між SUM та MAX. То вже мені на майбутнє :)
 

Ссылка на комментарий
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас
 Поделиться

  • Сейчас на странице   0 пользователей

    • Нет пользователей, просматривающих эту страницу.
×
×
  • Создать...

Важная информация

На нашем сайте используются файлы cookie и происходит обработка некоторых персональных данных пользователей, чтобы улучшить пользовательский интерфейс. Чтобы узнать для чего и какие персональные данные мы обрабатываем перейдите по ссылке. Если Вы нажмете «Я даю согласие», это означает, что Вы понимаете и принимаете все условия, указанные в этом Уведомлении о Конфиденциальности.