Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / UNION работает дольше, чем 3 SELECT по отдельности. / 21 сообщений из 21, страница 1 из 1
23.04.2015, 11:59:16
    #38943378
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
Делаю отчет по 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
23.04.2015, 12:14:08
    #38943415
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
И сколько же записей производит каждый из трёх запросов?
...
Рейтинг: 0 / 0
23.04.2015, 12:21:46
    #38943425
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
записей немного ~ 10тыс каждый.
...
Рейтинг: 0 / 0
23.04.2015, 12:25:02
    #38943430
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
А что показывает план выполнения? особенно на последнем этапе - слиянии...
...
Рейтинг: 0 / 0
23.04.2015, 12:49:00
    #38943461
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
Вот объединенный:
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
23.04.2015, 12:52:13
    #38943464
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
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
23.04.2015, 13:32:14
    #38943523
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
Посмотрел частные запросы... есть мелкие странности.
Вот например:

Код: 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
23.04.2015, 13:44:44
    #38943535
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
авторТак что из осмысленных советов рождается разве что реализация этого всего в процедуре со сливом записей во временную таблицу и потом селектом из неё.
это так и работает, с 10 минутной актуальностью им достаточно.

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

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

Тот запрос, я могу просто изъять и все равно оставшиеся считаются быстрее, чем объединенные UNION оба.
...
Рейтинг: 0 / 0
23.04.2015, 13:52:29
    #38943541
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
kpushМеня сам факт увеличения времени беспокоит, именно то, что я не понимаю.
Ну так почитай документацию про разницу между UNION и UNION ALL.
...
Рейтинг: 0 / 0
23.04.2015, 13:56:16
    #38943550
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
Dimitry Sibiryakov , у него как раз UNION ALL. Если посмотреть опубликованный код.
...
Рейтинг: 0 / 0
23.04.2015, 14:59:02
    #38943640
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
Код: 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
23.04.2015, 15:02:45
    #38943650
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
Код: 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
23.04.2015, 15:04:56
    #38943655
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
alex564657498765453я понимаю что двойное отрицание, это утверждения...А мож у него поле допускает NULL...
...
Рейтинг: 0 / 0
23.04.2015, 15:08:15
    #38943661
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
Код: 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
23.04.2015, 15:08:54
    #38943662
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
Akinaalex564657498765453я понимаю что двойное отрицание, это утверждения...А мож у него поле допускает NULL...

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

Такая архитектура, старались избежать дублирование информации.
...
Рейтинг: 0 / 0
23.04.2015, 15:36:14
    #38943688
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
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
23.04.2015, 15:59:21
    #38943703
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
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
23.04.2015, 18:14:53
    #38943835
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
kpushСейчас выкинул вообще эти под запросы, стало 7 секунд, а отдельные запросы вместе взятые меньше 1 секунды.
Придумываю, как этим воспользоваться, что бы улучшить показатели.
в конечном итоге добился только сокращения расчета временной таблицы с 30 до 20 секунд, на этом думаю отложить.

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

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

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

Все вернулось "на круги своя".
Теперь 0,7 секунды сразу итоговый отчет, без промежуточных таблиц.
...
Рейтинг: 0 / 0
24.04.2015, 16:09:44
    #38944782
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
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
24.04.2015, 17:25:42
    #38944867
kpush
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UNION работает дольше, чем 3 SELECT по отдельности.
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
Форумы / MySQL [игнор отключен] [закрыт для гостей] / UNION работает дольше, чем 3 SELECT по отдельности. / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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