powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / UNION работает дольше, чем 3 SELECT по отдельности.
21 сообщений из 21, страница 1 из 1
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943378
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Делаю отчет по 3 событиям собирая строки тремя разными SELECT.

По отдельности каждый из SELECT работают меньше секунды,
а объединенные в один запрос оператором UNION выполняются уже пол минуты.

Догадываюсь, что запросы криво составлены, индексов не хватает.
Оптимизатор видя их вместе ошибается с выбором индексов,
может быть есть легкий способ заставить его делать все запросы независимо и по отдельности.
Или еще как то оптимизировать объединенный запрос.

Спасибо.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
# accept
(select
item_offer.id as item_offer_id,
item.category_id as category_id,
ifnull(item.item_group_id,offer_item_group.item_group_id) as item_group_id,
round(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount),2) as "val_0_sum",
0 as "val_1_sum",
0 as "val_2_sum",
date(offer.last_accept_date) as `date`
FROM equipment.item_offer item_offer

join equipment.offer on (offer.id = item_offer.offer_id)
left join 
	(	select offer_accept.offer_id as offer_id
		from equipment.offer_accept 
		where offer_accept.allow <> 1) offer_accepted on offer_accepted.offer_id = offer.id

join equipment.item on (item.id = item_offer.item_id)
left join ( SELECT 
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.item_offer item_offer 
join equipment.item item on (item.id = item_offer.item_id)
group by item_offer.offer_id )offer_item_group on
 (offer_item_group.offer_id = item_offer.offer_id)
where  
offer.deleted = 0 and
 item_offer.state  not in ('DECLINED','MISSED') and
 offer_accepted.offer_id is null and
 offer.last_accept_date is not null
)

#payment
union all (SELECT 
item_offer.id as item_offer_id,
item.category_id as category_id,
ifnull(item.item_group_id,offer_item_group.item_group_id) as item_group_id,
0 as "val_0_sum",
round(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)*offer_payment.amount/offer_sum.offer_sum,2) as "val_1_sum",
0 as "val_2_sum",
offer_payment.payment_date as `date`
FROM equipment.item_offer item_offer
join equipment.offer on (offer.id = item_offer.offer_id)
join (SELECT 
	 offer.id as offer_id, 
     sum(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)) as offer_sum
FROM equipment.item_offer item_offer
join equipment.offer offer on (item_offer.offer_id = offer.id )
where 
 offer.deleted = 0 and
 item_offer.state not in ('DECLINED','MISSED')
group by offer.id)offer_sum on (offer_sum.offer_id = item_offer.offer_id)
join equipment.item on (item.id = item_offer.item_id)
join equipment.offer_payment offer_payment on (offer_payment.offer_id = item_offer.offer_id) 
left join ( SELECT 
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.item_offer item_offer 
join equipment.item item on (item.id = item_offer.item_id)
group by item_offer.offer_id )offer_item_group on
 (offer_item_group.offer_id = item_offer.offer_id)
where  
offer.deleted = 0 and
 item_offer.state  not in ('DECLINED','MISSED') and
 offer_payment.payment_date is not null
#delivery
)
UNION ALL
(
SELECT 
item_offer.id as item_offer_id,
item.category_id as category_id,
ifnull(item.item_group_id,delivery_item_group.item_group_id) as item_group_id,
0 as "val_0_sum",
0 as "val_1_sum",
round(if(item_offer.vat = 0, item_offer.price*delivery_item.delivered_count*1.18, item_offer.price*delivery_item.delivered_count),2) as "val_1_sum",
date(delivery.date) as `date`
FROM equipment.item_offer item_offer
join equipment.delivery_item delivery_item on (item_offer.id = delivery_item.item_offer_id)
join equipment.delivery delivery on (delivery.id = delivery_item.delivery_id)
join equipment.item on (item.id = delivery_item.item_id)
left join ( SELECT 
delivery_item.delivery_id as delivery_id,
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.delivery_item delivery_item
join equipment.item_offer item_offer on (item_offer.id = delivery_item.item_offer_id)
join equipment.delivery delivery on (delivery.id = delivery_item.delivery_id)
join equipment.item on (item.id = delivery_item.item_id)
group by delivery_item.delivery_id, item_offer.offer_id )delivery_item_group on
 (delivery_item_group.delivery_id = delivery_item.delivery_id) and (delivery_item_group.offer_id = item_offer.offer_id)
where delivery.delivered = 1 
and delivery_item.delivered_count > 0 
)

...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943415
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И сколько же записей производит каждый из трёх запросов?
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943425
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
записей немного ~ 10тыс каждый.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943430
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что показывает план выполнения? особенно на последнем этапе - слиянии...
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943461
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот объединенный:
idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra1PRIMARYofferALLPRIMARYNULLNULLNULL7821"Using where"1PRIMARYitem_offerref"fk_item_idxfk_offer_idx"fk_offer_idx9equipment.offer.id2"Using where"1PRIMARYitemeq_refPRIMARYPRIMARY8equipment.item_offer.item_id11PRIMARY<derived2>ALLNULLNULLNULLNULL76"Using where; Not exists"1PRIMARY<derived3>ALLNULLNULLNULLNULL76103DERIVEDitemindexPRIMARYfk_item_15NULL19107"Using index; Using temporary; Using filesort"3DERIVEDitem_offerreffk_item_idxfk_item_idx8equipment.item.id12DERIVEDoffer_acceptALLNULLNULLNULLNULL11061"Using where"4UNIONoffer_paymentALLNULLNULLNULLNULL4461"Using where"4UNIONitem_offerref"fk_item_idxfk_offer_idx"fk_offer_idx9equipment.offer_payment.offer_id2"Using where"4UNION<derived5>ALLNULLNULLNULLNULL5517"Using where; Using join buffer"4UNIONitemeq_refPRIMARYPRIMARY8equipment.item_offer.item_id14UNIONoffereq_refPRIMARYPRIMARY8equipment.offer_payment.offer_id1"Using where"4UNION<derived6>ALLNULLNULLNULLNULL76106DERIVEDitemindexPRIMARYfk_item_15NULL19107"Using index; Using temporary; Using filesort"6DERIVEDitem_offerreffk_item_idxfk_item_idx8equipment.item.id15DERIVEDofferindexPRIMARYPRIMARY8NULL3910"Using where"5DERIVEDitem_offerreffk_offer_idxfk_offer_idx9equipment.offer.id2"Using where"7UNIONdeliveryALLPRIMARYNULLNULLNULL4639"Using where"7UNIONdelivery_itemref"fk_delivery_item_1fk_delivery_item_2_idxfk_delivery_item_3_idx"fk_delivery_item_14equipment.delivery.id1"Using where"7UNIONitemeq_refPRIMARYPRIMARY8equipment.delivery_item.item_id17UNIONitem_offereq_refPRIMARYPRIMARY8equipment.delivery_item.item_offer_id17UNION<derived8>ALLNULLNULLNULLNULL44098DERIVEDdeliveryindexPRIMARYs_sp_idx5NULL4639"Using index; Using temporary; Using filesort"8DERIVEDdelivery_itemref"fk_delivery_item_1fk_delivery_item_2_idxfk_delivery_item_3_idx"fk_delivery_item_14equipment.delivery.id18DERIVEDitemeq_refPRIMARYPRIMARY8equipment.delivery_item.item_id18DERIVEDitem_offereq_refPRIMARYPRIMARY8equipment.delivery_item.item_offer_id1NULL"UNION RESULT""<union147>"ALLNULLNULLNULLNULLNULL



Это первый

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra1PRIMARYofferALLPRIMARYNULLNULLNULL7820"Using where"1PRIMARYitem_offerref"fk_item_idx;fk_offer_idx"fk_offer_idx9equipment.offer.id2"Using where"1PRIMARYitemeq_refPRIMARYPRIMARY8equipment.item_offer.item_id11PRIMARY<derived2>ALLNULLNULLNULLNULL76"Using where; Not exists"1PRIMARY<derived3>ALLNULLNULLNULLNULL76093DERIVEDitemindexPRIMARYfk_item_15NULL19099"Using index; Using temporary; Using filesort"3DERIVEDitem_offerreffk_item_idxfk_item_idx8equipment.item.id12DERIVEDoffer_acceptALLNULLNULLNULLNULL11059"Using where"


Второй

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra1PRIMARYoffer_paymentALLNULLNULLNULLNULL4460"Using where"1PRIMARYitem_offerref"fk_item_idx;fk_offer_idx"fk_offer_idx9equipment.offer_payment.offer_id2"Using where"1PRIMARY<derived2>ALLNULLNULLNULLNULL5516"Using where; Using join buffer"1PRIMARYitemeq_refPRIMARYPRIMARY8equipment.item_offer.item_id11PRIMARYoffereq_refPRIMARYPRIMARY8equipment.offer_payment.offer_id1"Using where"1PRIMARY<derived3>ALLNULLNULLNULLNULL76093DERIVEDitemindexPRIMARYfk_item_15NULL19107"Using index; Using temporary; Using filesort"3DERIVEDitem_offerreffk_item_idxfk_item_idx8equipment.item.id12DERIVEDofferindexPRIMARYPRIMARY8NULL3910"Using where"2DERIVEDitem_offerreffk_offer_idxfk_offer_idx9equipment.offer.id2"Using where"


Третий

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra1PRIMARYdeliveryALLPRIMARYNULLNULLNULL4639"Using where"1PRIMARYdelivery_itemref"fk_delivery_item_1;fk_delivery_item_2_idx;fk_delivery_item_3_idx"fk_delivery_item_14equipment.delivery.id1"Using where"1PRIMARYitemeq_refPRIMARYPRIMARY8equipment.delivery_item.item_id11PRIMARYitem_offereq_refPRIMARYPRIMARY8equipment.delivery_item.item_offer_id11PRIMARY<derived2>ALLNULLNULLNULLNULL44092DERIVEDdeliveryindexPRIMARYs_sp_idx5NULL4639"Using index; Using temporary; Using filesort"2DERIVEDdelivery_itemref"fk_delivery_item_1;fk_delivery_item_2_idx;fk_delivery_item_3_idx"fk_delivery_item_14equipment.delivery.id12DERIVEDitemeq_refPRIMARYPRIMARY8equipment.delivery_item.item_id12DERIVEDitem_offereq_refPRIMARYPRIMARY8equipment.delivery_item.item_offer_id1
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943464
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina, вот точнее, (в прошлый раз таблица разъехалась)

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra1PRIMARYofferALLPRIMARYNULLNULLNULL7821"Using where"1PRIMARYitem_offerref"fk_item_idx;fk_offer_idx"fk_offer_idx9equipment.offer.id2"Using where"1PRIMARYitemeq_refPRIMARYPRIMARY8equipment.item_offer.item_id11PRIMARY<derived2>ALLNULLNULLNULLNULL76"Using where; Not exists"1PRIMARY<derived3>ALLNULLNULLNULLNULL76103DERIVEDitemindexPRIMARYfk_item_15NULL19107"Using index; Using temporary; Using filesort"3DERIVEDitem_offerreffk_item_idxfk_item_idx8equipment.item.id12DERIVEDoffer_acceptALLNULLNULLNULLNULL11061"Using where"4UNIONoffer_paymentALLNULLNULLNULLNULL4461"Using where"4UNIONitem_offerref"fk_item_idx;fk_offer_idx"fk_offer_idx9equipment.offer_payment.offer_id2"Using where"4UNION<derived5>ALLNULLNULLNULLNULL5517"Using where; Using join buffer"4UNIONitemeq_refPRIMARYPRIMARY8equipment.item_offer.item_id14UNIONoffereq_refPRIMARYPRIMARY8equipment.offer_payment.offer_id1"Using where"4UNION<derived6>ALLNULLNULLNULLNULL76106DERIVEDitemindexPRIMARYfk_item_15NULL19107"Using index; Using temporary; Using filesort"6DERIVEDitem_offerreffk_item_idxfk_item_idx8equipment.item.id15DERIVEDofferindexPRIMARYPRIMARY8NULL3910"Using where"5DERIVEDitem_offerreffk_offer_idxfk_offer_idx9equipment.offer.id2"Using where"7UNIONdeliveryALLPRIMARYNULLNULLNULL4639"Using where"7UNIONdelivery_itemref"fk_delivery_item_1;fk_delivery_item_2_idx;fk_delivery_item_3_idx"fk_delivery_item_14equipment.delivery.id1"Using where"7UNIONitemeq_refPRIMARYPRIMARY8equipment.delivery_item.item_id17UNIONitem_offereq_refPRIMARYPRIMARY8equipment.delivery_item.item_offer_id17UNION<derived8>ALLNULLNULLNULLNULL44098DERIVEDdeliveryindexPRIMARYs_sp_idx5NULL4639"Using index; Using temporary; Using filesort"8DERIVEDdelivery_itemref"fk_delivery_item_1;fk_delivery_item_2_idx;fk_delivery_item_3_idx"fk_delivery_item_14equipment.delivery.id18DERIVEDitemeq_refPRIMARYPRIMARY8equipment.delivery_item.item_id18DERIVEDitem_offereq_refPRIMARYPRIMARY8equipment.delivery_item.item_offer_id1NULL"UNION RESULT""<union1;4;7>"ALLNULLNULLNULLNULLNULL
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943523
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотрел частные запросы... есть мелкие странности.
Вот например:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
SELECT
item_offer.id AS item_offer_id,
item.category_id AS category_id,
IFNULL(item.item_group_id,offer_item_group.item_group_id) AS item_group_id,
ROUND(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount),2) AS "val_0_sum",
0 AS "val_1_sum",
0 AS "val_2_sum",
DATE(offer.last_accept_date) AS `date`

FROM equipment.item_offer item_offer
JOIN equipment.offer ON (offer.id = item_offer.offer_id)
LEFT JOIN 
(	SELECT offer_accept.offer_id AS offer_id
	FROM equipment.offer_accept 
	WHERE offer_accept.allow <> 1
) offer_accepted ON offer_accepted.offer_id = offer.id
JOIN equipment.item ON (item.id = item_offer.item_id)
LEFT JOIN 
(	SELECT 
	item_offer.offer_id AS offer_id,
	MAX(item.item_group_id) AS item_group_id
	FROM equipment.item_offer item_offer 
	JOIN equipment.item item ON (item.id = item_offer.item_id)
	GROUP BY item_offer.offer_id 
) offer_item_group ON offer_item_group.offer_id = item_offer.offer_id

WHERE  
offer.deleted = 0 
AND item_offer.state NOT in ('DECLINED','MISSED') 
AND offer_accepted.offer_id IS NULL 
AND offer.last_accept_date IS NOT NULL



НЕ нра вот эта часть:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
-- ...
LEFT JOIN 
(	SELECT offer_accept.offer_id AS offer_id
	FROM equipment.offer_accept 
	WHERE offer_accept.allow <> 1
) offer_accepted ON offer_accepted.offer_id = offer.id
-- ...
WHERE  
-- ...
AND offer_accepted.offer_id IS NULL 
-- ...


Перерисуй её на WHERE NOT EXISTS, что ли.

Что до окончательного запроса - я не понимаю, откуда появляются лишние сортировки. Так что из осмысленных советов рождается разве что реализация этого всего в процедуре со сливом записей во временную таблицу и потом селектом из неё.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943535
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторТак что из осмысленных советов рождается разве что реализация этого всего в процедуре со сливом записей во временную таблицу и потом селектом из неё.
это так и работает, с 10 минутной актуальностью им достаточно.

Меня сам факт увеличения времени беспокоит, именно то, что я не понимаю.

В общем буду копать.

Тот запрос, я могу просто изъять и все равно оставшиеся считаются быстрее, чем объединенные UNION оба.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943541
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kpushМеня сам факт увеличения времени беспокоит, именно то, что я не понимаю.
Ну так почитай документацию про разницу между UNION и UNION ALL.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943550
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov , у него как раз UNION ALL. Если посмотреть опубликованный код.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943640
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
# accept
(
	select 	item_offer.id AS item_offer_id,
				item.category_id AS category_id,
				IFNULL(item.item_group_id,offer_item_group.item_group_id) AS item_group_id,
				ROUND(
					IF(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount),2
				) AS "val_0_sum",
				0 AS "val_1_sum",
				0 AS "val_2_sum",
				DATE(offer.last_accept_date) AS `date`
	FROM 
		item_offer item_offer
		JOIN offer ON (offer.id = item_offer.offer_id)
		LEFT JOIN 
			(
				SELECT offer_accept.offer_id AS offer_id
				FROM offer_accept 
				WHERE offer_accept.allow <> 1
			) offer_accepted ON offer_accepted.offer_id = offer.id

		JOIN item on (item.id = item_offer.item_id)
		LEFT JOIN 
			(
				SELECT item_offer.offer_id AS offer_id,
						max(item.item_group_id) AS item_group_id
				FROM 
					item_offer item_offer 
					JOIN item item ON (item.id = item_offer.item_id)
				GROUP BY item_offer.offer_id
			)offer_item_group on (offer_item_group.offer_id = item_offer.offer_id)
	WHERE  
		offer.deleted = 0 and
		item_offer.state  not in ('DECLINED','MISSED') and
		offer_accepted.offer_id is null and
		offer.last_accept_date is not null
)

#payment
UNION ALL 
(
	SELECT 	item_offer.id AS item_offer_id,
			item.category_id AS category_id,
			ifnull(item.item_group_id,offer_item_group.item_group_id) AS item_group_id,
			0 AS "val_0_sum",
			round(
				if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)*
					offer_payment.amount/offer_sum.offer_sum,2
			) AS "val_1_sum",
			0 AS "val_2_sum",
			offer_payment.payment_date AS `date`
	FROM 
		item_offer item_offer
		JOIN offer on (offer.id = item_offer.offer_id)
		JOIN
			(
				SELECT offer.id AS offer_id, 
						sum(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)) AS offer_sum
				FROM 
					item_offer item_offer
					JOIN offer offer on (item_offer.offer_id = offer.id )
				WHERE 
					offer.deleted = 0 and
					item_offer.state not in ('DECLINED','MISSED')
				group by offer.id
			)offer_sum on (offer_sum.offer_id = item_offer.offer_id)
		JOIN item on (item.id = item_offer.item_id)
		JOIN offer_payment offer_payment on (offer_payment.offer_id = item_offer.offer_id) 
		LEFT JOIN
			(
				SELECT item_offer.offer_id AS offer_id,
						max(item.item_group_id) AS item_group_id
				FROM 
					item_offer item_offer 
					JOIN item item on (item.id = item_offer.item_id)
				group by item_offer.offer_id
			)offer_item_group on (offer_item_group.offer_id = item_offer.offer_id)
	WHERE  
		offer.deleted = 0 and
		item_offer.state  not in ('DECLINED','MISSED') and
		offer_payment.payment_date is not null
#delivery
)
UNION ALL
(
	SELECT 	item_offer.id AS item_offer_id,
			item.category_id AS category_id,
			ifnull(item.item_group_id,delivery_item_group.item_group_id) AS item_group_id,
			0 AS "val_0_sum",
			0 AS "val_1_sum",
			round(if(item_offer.vat = 0, item_offer.price*delivery_item.delivered_count*1.18, item_offer.price*delivery_item.delivered_count),2) AS "val_1_sum",
			date(delivery.date) AS `date`
	FROM 
		item_offer item_offer
		JOIN delivery_item delivery_item on (item_offer.id = delivery_item.item_offer_id)
		JOIN delivery delivery on (delivery.id = delivery_item.delivery_id)
		JOIN item on (item.id = delivery_item.item_id)
		LEFT JOIN
			(
				SELECT 	delivery_item.delivery_id AS delivery_id,
						item_offer.offer_id AS offer_id,
						max(item.item_group_id) AS item_group_id
				FROM 
					delivery_item delivery_item
					JOIN item_offer item_offer on (item_offer.id = delivery_item.item_offer_id)
					JOIN delivery delivery on (delivery.id = delivery_item.delivery_id)
					JOIN item on (item.id = delivery_item.item_id)
				group by delivery_item.delivery_id, item_offer.offer_id 
			)delivery_item_group on (delivery_item_group.delivery_id = delivery_item.delivery_id) 
				and (delivery_item_group.offer_id = item_offer.offer_id)
	where
		delivery.delivered = 1 and delivery_item.delivered_count > 0 
)
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943650
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
LEFT JOIN 
			(
				SELECT offer_accept.offer_id AS offer_id
				FROM offer_accept 
				WHERE offer_accept.allow <> 1
			) offer_accepted ON offer_accepted.offer_id = offer.id

...
WHERE
...
offer_accepted.offer_id is null
...



ТС, тебя ничего не смущает - находим список айдишников, для которых Эллоу не равно 1, и берём айдишники, которые не в этом
списке. я понимаю что двойное отрицание, это утверждения... но в даннос ситуации, - ты чего творишь то!?
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943655
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453я понимаю что двойное отрицание, это утверждения...А мож у него поле допускает NULL...
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943661
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
	IFNULL(item.item_group_id,offer_item_group.item_group_id) AS item_group_id,



для вычисления offer_item_group.item_group_id нихилый такой подзапрос...

это точно надо?
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943662
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akinaalex564657498765453я понимаю что двойное отрицание, это утверждения...А мож у него поле допускает NULL...

в общем то да, NULL когда решение не принято.

Такая архитектура, старались избежать дублирование информации.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943688
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex564657498765453
Код: sql
1.
	IFNULL(item.item_group_id,offer_item_group.item_group_id) AS item_group_id,



для вычисления offer_item_group.item_group_id нихилый такой подзапрос...

это точно надо?

иногда добавляют строчку счета не из заявки, (т.е. equipment.item с item_group_id Null окажется)
когда например доставку в счет вставляют или сборку или хрень какую то дополнительную.

Тогда делаем предположение, что расход по этому должен нести тот кто заказывал все остальное в этом счете.

Такая же конструкция с доставками, нам все, что вошло в один счет и попало в одну доставку "вешается" на один заказ.

Пробовал это выкидывать на уровень верхних (не указанных здесь запросов)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
(select
item_offer.id as item_offer_id,
offer_item_group.item_group_id as assumption_item_group_id,
round(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount),2) as "val_0_sum",
0 as "val_1_sum",
0 as "val_2_sum",
date(offer.last_accept_date) as `date`
FROM equipment.item_offer item_offer

join equipment.offer on (offer.id = item_offer.offer_id)
left join 
	(	select offer_accept.offer_id as offer_id
		from equipment.offer_accept 
		where offer_accept.allow <> 1) offer_accepted on offer_accepted.offer_id = offer.id

join equipment.item on (item.id = item_offer.item_id)
left join ( SELECT 
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.item_offer item_offer 
join equipment.item item on (item.id = item_offer.item_id)
group by item_offer.offer_id )offer_item_group on
 (offer_item_group.offer_id = item_offer.offer_id)
where  
offer.deleted = 0 and
 item_offer.state  not in ('DECLINED','MISSED') and
 offer_accepted.offer_id is null and
 offer.last_accept_date is not null
)
union all (SELECT 
item_offer.id as item_offer_id,
offer_item_group.item_group_id as assumption_item_group_id,
0 as "val_0_sum",
round(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)*offer_payment.amount/offer_sum.offer_sum,2) as "val_1_sum",
0 as "val_2_sum",
offer_payment.payment_date as `date`
FROM equipment.item_offer item_offer
join equipment.offer on (offer.id = item_offer.offer_id)
join (SELECT 
	 offer.id as offer_id, 
     sum(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)) as offer_sum
FROM equipment.item_offer item_offer
join equipment.offer offer on (item_offer.offer_id = offer.id )
where 
 offer.deleted = 0 and
 item_offer.state not in ('DECLINED','MISSED')
group by offer.id)offer_sum on (offer_sum.offer_id = item_offer.offer_id)
join equipment.offer_payment offer_payment on (offer_payment.offer_id = item_offer.offer_id) 
left join ( SELECT 
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.item_offer item_offer 
join equipment.item item on (item.id = item_offer.item_id)
group by item_offer.offer_id )offer_item_group on
 (offer_item_group.offer_id = item_offer.offer_id)
where  
offer.deleted = 0 and
 item_offer.state  not in ('DECLINED','MISSED') and
 offer_payment.payment_date is not null
#delivery
)
UNION ALL
(
SELECT 
item_offer.id as item_offer_id,
delivery_item_group.item_group_id as assumption_item_group_id,
0 as "val_0_sum",
0 as "val_1_sum",
round(if(item_offer.vat = 0, item_offer.price*delivery_item.delivered_count*1.18, item_offer.price*delivery_item.delivered_count),2) as "val_2_sum",
date(delivery.date) as `date`
FROM equipment.item_offer item_offer
join equipment.delivery_item delivery_item on (item_offer.id = delivery_item.item_offer_id)
join equipment.delivery delivery on (delivery.id = delivery_item.delivery_id)
left join ( SELECT 
delivery_item.delivery_id as delivery_id,
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.delivery_item delivery_item
join equipment.item item on (item.id = delivery_item.item_id)
join equipment.item_offer item_offer on (item_offer.id = delivery_item.item_offer_id)
join equipment.delivery delivery on (delivery.id = delivery_item.delivery_id)
group by delivery_item.delivery_id, item_offer.offer_id )delivery_item_group on
 (delivery_item_group.delivery_id = delivery_item.delivery_id) and (delivery_item_group.offer_id = item_offer.offer_id)
where delivery.delivered = 1 
and delivery_item.delivered_count > 0 
)



, скорость не изменилась.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943703
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kpushalex564657498765453
Код: sql
1.
	IFNULL(item.item_group_id,offer_item_group.item_group_id) AS item_group_id,



для вычисления offer_item_group.item_group_id нихилый такой подзапрос...

это точно надо?

иногда добавляют строчку счета не из заявки, (т.е. equipment.item с item_group_id Null окажется)
когда например доставку в счет вставляют или сборку или хрень какую то дополнительную.

Тогда делаем предположение, что расход по этому должен нести тот кто заказывал все остальное в этом счете.

Такая же конструкция с доставками, нам все, что вошло в один счет и попало в одну доставку "вешается" на один заказ.

Пробовал это выкидывать на уровень верхних (не указанных здесь запросов)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
(select
item_offer.id as item_offer_id,
offer_item_group.item_group_id as assumption_item_group_id,
round(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount),2) as "val_0_sum",
0 as "val_1_sum",
0 as "val_2_sum",
date(offer.last_accept_date) as `date`
FROM equipment.item_offer item_offer

join equipment.offer on (offer.id = item_offer.offer_id)
left join 
	(	select offer_accept.offer_id as offer_id
		from equipment.offer_accept 
		where offer_accept.allow <> 1) offer_accepted on offer_accepted.offer_id = offer.id

join equipment.item on (item.id = item_offer.item_id)
left join ( SELECT 
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.item_offer item_offer 
join equipment.item item on (item.id = item_offer.item_id)
group by item_offer.offer_id )offer_item_group on
 (offer_item_group.offer_id = item_offer.offer_id)
where  
offer.deleted = 0 and
 item_offer.state  not in ('DECLINED','MISSED') and
 offer_accepted.offer_id is null and
 offer.last_accept_date is not null
)
union all (SELECT 
item_offer.id as item_offer_id,
offer_item_group.item_group_id as assumption_item_group_id,
0 as "val_0_sum",
round(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)*offer_payment.amount/offer_sum.offer_sum,2) as "val_1_sum",
0 as "val_2_sum",
offer_payment.payment_date as `date`
FROM equipment.item_offer item_offer
join equipment.offer on (offer.id = item_offer.offer_id)
join (SELECT 
	 offer.id as offer_id, 
     sum(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)) as offer_sum
FROM equipment.item_offer item_offer
join equipment.offer offer on (item_offer.offer_id = offer.id )
where 
 offer.deleted = 0 and
 item_offer.state not in ('DECLINED','MISSED')
group by offer.id)offer_sum on (offer_sum.offer_id = item_offer.offer_id)
join equipment.offer_payment offer_payment on (offer_payment.offer_id = item_offer.offer_id) 
left join ( SELECT 
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.item_offer item_offer 
join equipment.item item on (item.id = item_offer.item_id)
group by item_offer.offer_id )offer_item_group on
 (offer_item_group.offer_id = item_offer.offer_id)
where  
offer.deleted = 0 and
 item_offer.state  not in ('DECLINED','MISSED') and
 offer_payment.payment_date is not null
#delivery
)
UNION ALL
(
SELECT 
item_offer.id as item_offer_id,
delivery_item_group.item_group_id as assumption_item_group_id,
0 as "val_0_sum",
0 as "val_1_sum",
round(if(item_offer.vat = 0, item_offer.price*delivery_item.delivered_count*1.18, item_offer.price*delivery_item.delivered_count),2) as "val_2_sum",
date(delivery.date) as `date`
FROM equipment.item_offer item_offer
join equipment.delivery_item delivery_item on (item_offer.id = delivery_item.item_offer_id)
join equipment.delivery delivery on (delivery.id = delivery_item.delivery_id)
left join ( SELECT 
delivery_item.delivery_id as delivery_id,
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.delivery_item delivery_item
join equipment.item item on (item.id = delivery_item.item_id)
join equipment.item_offer item_offer on (item_offer.id = delivery_item.item_offer_id)
join equipment.delivery delivery on (delivery.id = delivery_item.delivery_id)
group by delivery_item.delivery_id, item_offer.offer_id )delivery_item_group on
 (delivery_item_group.delivery_id = delivery_item.delivery_id) and (delivery_item_group.offer_id = item_offer.offer_id)
where delivery.delivered = 1 
and delivery_item.delivered_count > 0 
)



, скорость не изменилась.

Сейчас выкинул вообще эти под запросы, стало 7 секунд, а отдельные запросы вместе взятые меньше 1 секунды.
Придумываю, как этим воспользоваться, что бы улучшить показатели.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38943835
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kpushСейчас выкинул вообще эти под запросы, стало 7 секунд, а отдельные запросы вместе взятые меньше 1 секунды.
Придумываю, как этим воспользоваться, что бы улучшить показатели.
в конечном итоге добился только сокращения расчета временной таблицы с 30 до 20 секунд, на этом думаю отложить.

Спасибо за поддержку.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38944655
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kpushв конечном итоге добился только сокращения расчета временной таблицы с 30 до 20 секунд, на этом думаю отложить.

Спасибо за поддержку.

Убрал в исходном запросе SUBSELECTы по расчету суммы и недостающих номеров заказов,
т.к. их актуализация каждые 5 минут достаточна для дела.
Из пересчет занимает 3 секунды в сумме.

Все вернулось "на круги своя".
Теперь 0,7 секунды сразу итоговый отчет, без промежуточных таблиц.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38944782
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kpushalex564657498765453
Код: sql
1.
	IFNULL(item.item_group_id,offer_item_group.item_group_id) AS item_group_id,



для вычисления offer_item_group.item_group_id нихилый такой подзапрос...

это точно надо?

иногда добавляют строчку счета не из заявки, (т.е. equipment.item с item_group_id Null окажется)
когда например доставку в счет вставляют или сборку или хрень какую то дополнительную.

Тогда делаем предположение, что расход по этому должен нести тот кто заказывал все остальное в этом счете.

Такая же конструкция с доставками, нам все, что вошло в один счет и попало в одну доставку "вешается" на один заказ.

Пробовал это выкидывать на уровень верхних (не указанных здесь запросов)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
(select
item_offer.id as item_offer_id,
offer_item_group.item_group_id as assumption_item_group_id,
round(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount),2) as "val_0_sum",
0 as "val_1_sum",
0 as "val_2_sum",
date(offer.last_accept_date) as `date`
FROM equipment.item_offer item_offer

join equipment.offer on (offer.id = item_offer.offer_id)
left join 
	(	select offer_accept.offer_id as offer_id
		from equipment.offer_accept 
		where offer_accept.allow <> 1) offer_accepted on offer_accepted.offer_id = offer.id

join equipment.item on (item.id = item_offer.item_id)
left join ( SELECT 
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.item_offer item_offer 
join equipment.item item on (item.id = item_offer.item_id)
group by item_offer.offer_id )offer_item_group on
 (offer_item_group.offer_id = item_offer.offer_id)
where  
offer.deleted = 0 and
 item_offer.state  not in ('DECLINED','MISSED') and
 offer_accepted.offer_id is null and
 offer.last_accept_date is not null
)
union all (SELECT 
item_offer.id as item_offer_id,
offer_item_group.item_group_id as assumption_item_group_id,
0 as "val_0_sum",
round(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)*offer_payment.amount/offer_sum.offer_sum,2) as "val_1_sum",
0 as "val_2_sum",
offer_payment.payment_date as `date`
FROM equipment.item_offer item_offer
join equipment.offer on (offer.id = item_offer.offer_id)
join (SELECT 
	 offer.id as offer_id, 
     sum(if(item_offer.vat = 0, item_offer.amount*1.18, item_offer.amount)) as offer_sum
FROM equipment.item_offer item_offer
join equipment.offer offer on (item_offer.offer_id = offer.id )
where 
 offer.deleted = 0 and
 item_offer.state not in ('DECLINED','MISSED')
group by offer.id)offer_sum on (offer_sum.offer_id = item_offer.offer_id)
join equipment.offer_payment offer_payment on (offer_payment.offer_id = item_offer.offer_id) 
left join ( SELECT 
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.item_offer item_offer 
join equipment.item item on (item.id = item_offer.item_id)
group by item_offer.offer_id )offer_item_group on
 (offer_item_group.offer_id = item_offer.offer_id)
where  
offer.deleted = 0 and
 item_offer.state  not in ('DECLINED','MISSED') and
 offer_payment.payment_date is not null
#delivery
)
UNION ALL
(
SELECT 
item_offer.id as item_offer_id,
delivery_item_group.item_group_id as assumption_item_group_id,
0 as "val_0_sum",
0 as "val_1_sum",
round(if(item_offer.vat = 0, item_offer.price*delivery_item.delivered_count*1.18, item_offer.price*delivery_item.delivered_count),2) as "val_2_sum",
date(delivery.date) as `date`
FROM equipment.item_offer item_offer
join equipment.delivery_item delivery_item on (item_offer.id = delivery_item.item_offer_id)
join equipment.delivery delivery on (delivery.id = delivery_item.delivery_id)
left join ( SELECT 
delivery_item.delivery_id as delivery_id,
item_offer.offer_id as offer_id,
max(item.item_group_id) as item_group_id
FROM equipment.delivery_item delivery_item
join equipment.item item on (item.id = delivery_item.item_id)
join equipment.item_offer item_offer on (item_offer.id = delivery_item.item_offer_id)
join equipment.delivery delivery on (delivery.id = delivery_item.delivery_id)
group by delivery_item.delivery_id, item_offer.offer_id )delivery_item_group on
 (delivery_item_group.delivery_id = delivery_item.delivery_id) and (delivery_item_group.offer_id = item_offer.offer_id)
where delivery.delivered = 1 
and delivery_item.delivered_count > 0 
)



, скорость не изменилась.

и вопрос остаёться в силе, зачем групировку делать? то-есть у тебя этот айди либо нету, либо такойже как для любого елемента группы?? тоесть тебе по сути нужен любой елемент где не нулл требуемый айдишник.
...
Рейтинг: 0 / 0
UNION работает дольше, чем 3 SELECT по отдельности.
    #38944867
kpush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex564657498765453и вопрос остаёться в силе, зачем групировку делать? то-есть у тебя этот айди либо нету, либо такойже как для любого елемента группы?? тоесть тебе по сути нужен любой елемент где не нулл требуемый айдишник.

Эту группировку я то же убрал тем, ввел новое поле: item.tmp_item_group_id и заранее его вычисляю,
если нет значения "номера группы" в основном item.item_group_id .

Вот такой процедурой:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
update equipment.item 
join equipment.item_offer item_offer on (item.id = item_offer.item_id)
left join ( SELECT 
                          item_offer.offer_id as offer_id,
                          max(item.item_group_id) as item_group_id
              FROM equipment.item_offer item_offer 
              join equipment.item item on (item.id = item_offer.item_id)
              group by item_offer.offer_id )offer_item_group on
             (offer_item_group.offer_id = item_offer.offer_id)
set item.tmp_item_group_id = offer_item_group.item_group_id
where 
item.item_group_id is null 
and
item.tmp_item_group_id is null;



Сумму счета offer_sum.offer_sum вычисляю то же заранее.

И отчет становится быстрее.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / UNION работает дольше, чем 3 SELECT по отдельности.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]