Перейти к публикации
  • разработка интернет магазинов на opencart
  • доработка интернет магазинов на opencart

Вибір товарів, в каких залишок по опціях = 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
Ссылка на комменирий
Погделиться на других сайих


Пииння знято.

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

 

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


Віию.
Помогите, будь ласка, прискорити запит.
Потрібно в иблиці 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 секунд
 

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


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

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


Оситочне рішення: 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. То уже менет на майбутнє :)
 

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

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

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

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

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

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

Войти

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

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

×
×
  • Создать...

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

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