Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите оптимизировать запрос  [new]
gerasim9393
Member

Откуда:
Сообщений: 5
Добрый день.
есть некий запрос созданный неким разработчиком:
set profiling=1;
SELECT 
	DISTINCT p.product_id,
	pd.name AS name, 
	p.image, 
	p.city as zone, 
	p.href as product_url, 
	p.product_id as product_id, 
	p.shipping_text as shipping_text, 
	p.payment_text as payment_text,
	p.sort_order, 
	p.shipping as shipping, 
	p.sort_order, 
	v.partner, 
	v.store_url as out_href, 
	co.name as country, 
	(SELECT price FROM product_discount pd2 WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = '1' AND pd2.quantity = '1' 
		AND ((pd2.date_start = '0000-00-00' OR pd2.date_start < '2016-08-24 11:45:00') 
		AND (pd2.date_end = '0000-00-00' OR pd2.date_end > '2016-08-24 11:45:00')) 
		ORDER BY pd2.priority ASC, pd2.price ASC LIMIT 1) AS discount, 
	(SELECT price FROM product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '1' 
		AND ((ps.date_start = '0000-00-00' OR ps.date_start < '2016-08-24 11:45:00') 
		AND (ps.date_end = '0000-00-00' OR ps.date_end > '2016-08-24 11:45:00')) 
		ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) AS special, 
	(SELECT points FROM product_reward pr WHERE pr.product_id = p.product_id AND pr.customer_group_id = '1') AS reward, 
	(SELECT ss.name FROM stock_status ss WHERE ss.stock_status_id = p.stock_status_id AND ss.language_id = '8') AS stock_status, 
	(SELECT wcd.unit FROM weight_class_description wcd WHERE p.weight_class_id = wcd.weight_class_id AND wcd.language_id = '8') AS weight_class, 
	(SELECT lcd.unit FROM length_class_description lcd WHERE p.length_class_id = lcd.length_class_id AND lcd.language_id = '8') AS length_class, 
	(SELECT AVG(rating) AS total FROM review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating, 
	(SELECT COUNT(*) AS total FROM review r2 WHERE r2.product_id = p.product_id AND r2.status = '1' GROUP BY r2.product_id) AS reviews
FROM product p 
INNER JOIN product_description pd ON (p.product_id = pd.product_id) 
LEFT JOIN product_to_store p2s ON (p.product_id = p2s.product_id) 
INNER JOIN country co ON (p.country_id = co.country_id) 
INNER JOIN vendor vv ON (vv.vproduct_id = p.product_id) 
INNER JOIN vendors v ON (vv.vendor = v.vendor_id) 
WHERE p.product_id = '337388' 
	AND pd.language_id = '8' 
	AND p.status = '1' 
	AND p.date_available <= '2016-08-24 11:45:00';
    show profiles;
24 авг 16, 14:08    [19584590]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
gerasim9393
Member

Откуда:
Сообщений: 5
который выдает такой вывод http://shot.qip.ru/00PJSZ-2AD7h4cdS/
мне необходимо его оптимизировать. не вдаваясь в тонкие подробности. я как бы не привожу код запроса на создание таблиц, ибо не флудить (очень много коду будет). мне бы лишь тыкнуть на что смотреть и краткие рекомендации возникающие у опытных и умелых бд-шников с первого взгляда. ибо explain юзать не умею особо и не понимаю почему у меня несколько таблиц в table пишут NULL. что это означает? и что означают комментарии в Extra около них?
в целом вопрос хотел бы задать так: как проводится оптимизация запросов грамотно? какими инструментами, в какой последовательности, и т.д...
Спасибо.
24 авг 16, 14:15    [19584625]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
gerasim9393
Member

Откуда:
Сообщений: 5
также хочу добавить что сначала стоял DISTINCT *. потом я поставил DISTINCT p.product_id
24 авг 16, 14:17    [19584639]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
gerasim9393
мне бы лишь тыкнуть на что смотреть
Ошиблись форумом - ваш запрос для MySQL.
24 авг 16, 14:19    [19584650]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
o-o
Guest
ORDER BY ... LIMIT 1 --> MySQL
24 авг 16, 14:19    [19584656]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
gerasim9393
Member

Откуда:
Сообщений: 5
invm,

дико извиняюсь, и большое спасибо! думал форумчан это не смутит((((
24 авг 16, 14:20    [19584667]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
gerasim9393
думал форумчан это не смутит((((
У вас же не возникает желания лечить, например, глаза у проктолога, а не у офтальмолога, хотя они оба врачи?
24 авг 16, 14:25    [19584691]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
o-o
Guest
invm
gerasim9393
думал форумчан это не смутит((((
У вас же не возникает желания лечить, например, глаза у проктолога, а не у офтальмолога, хотя они оба врачи?

это смотря где. в Японии запросто.
Человек - в попе-глаз
24 авг 16, 14:46    [19584845]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
aleks2
Guest
gerasim9393
также хочу добавить что сначала стоял DISTINCT *. потом я поставил DISTINCT p.product_id


1. DISTINCT действует на весь список полей. Это группировка, типа group by <все поля select>.
2. Это главный тормоз. Ибо группировка соединения шести таблиц - это издевательство над сервером и здравым смыслом.
3. От DISTINCT надо избавиться.

Ваша Му-Му.
24 авг 16, 15:04    [19584992]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31983
aleks2
1. DISTINCT действует на весь список полей. Это группировка, типа group by <все поля select>.
2. Это главный тормоз. Ибо группировка соединения шести таблиц - это издевательство над сервером и здравым смыслом.
3. От DISTINCT надо избавиться.
... убрав LEFT JOIN product_to_store p2s
24 авг 16, 18:08    [19586034]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Megabyte
Member

Откуда: ближайшее заМКАДье
Сообщений: 4997
Убрать все (SELECT ... FROM ) в секции SELECT, т.к. подзапрос в данном случае будет выполняться столько раз, сколько строк в базовом запросе. По крайней мере в MS SQL так. Переписать на JOIN.
26 авг 16, 15:41    [19594962]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
o-o
Guest
Megabyte
подзапрос в данном случае будет выполняться столько раз, сколько строк в базовом запросе. По крайней мере в MS SQL так. Переписать на JOIN.

26 авг 16, 16:02    [19595040]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
o-o
Guest
Megabyte,

если у меня запрос
select *,
 (select count(*) from dbo.nums )as cnt
from dbo.nums

и у меня в нумсе 1млн строк, сколько строк будет прочитано для выполнения этого запроса?
ну т.е. пусть
select * from dbo.nums
это 3000 чтений,
тогда на запрос с каунтом в подзапросе сколько чтений потребуется?
26 авг 16, 16:15    [19595090]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
Megabyte
Member

Откуда: ближайшее заМКАДье
Сообщений: 4997
o-o
Megabyte,

если у меня запрос
select *,
 (select count(*) from dbo.nums )as cnt
from dbo.nums

и у меня в нумсе 1млн строк, сколько строк будет прочитано для выполнения этого запроса?
ну т.е. пусть
select * from dbo.nums
это 3000 чтений,
тогда на запрос с каунтом в подзапросе сколько чтений потребуется?

Сорри, я загнался конечно, в общем случае не так.

Но в частном случае может, когда 2 параметра из одной таблицы отдельными подзапросами вычисляются, в итоге кол-во обращений к таблице будет в 2 раза больше, нежели с join.

з.ы. да и вообще кмк подзапросы в SELECT ухудшают наглядность.
26 авг 16, 17:38    [19595580]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать запрос  [new]
o-o
Guest
Megabyte
Но в частном случае может, когда 2 параметра из одной таблицы отдельными подзапросами вычисляются, в итоге кол-во обращений к таблице будет в 2 раза больше, нежели с join
.

Так это совсем другое дело, конечно же, если можно посчитать, например, 2 разных агрегата, те же count и sum по одной и той же таблице, то чем их разносить по двум подзапросам в селекте, проще 1 раз в одном посчитать и приджойнить через cross join.
Но у ТС все таблицы разные и ничего объединить не получится.
А SQL Server перед MySQL-щиком позорить негоже, типа не догадались всего раз посчитать, на каждую строку пересчитывают, о ужас
26 авг 16, 18:49    [19595846]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить