Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Ускорить запрос / 18 сообщений из 18, страница 1 из 1
11.11.2016, 13:32
    #39345567
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
Запрос выполняется очень медленно. Это внутренняя часть, выделенная из общего запроса, и она выдает 2 записи и выполняется 2 секунды. Полный запрос, в котором 400 записей, соответственно, выполняется 4 минуты.
Как оптимизировать запрос? Можно ли переписать на Join?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT cry1.weight_brutto_remains 
FROM cargo_remains cry1 
INNER JOIN cargo_card cc1 ON cc1.id = cry1.cargo_card_id 
INNER JOIN placement_cargo_card pcc1 ON pcc1.id = cc1.id 
INNER JOIN contract_cargo_sub ccs1 ON ccs1.id = cc1.contract_cargo_sub_id 
INNER JOIN contract_cargo_consignment ccc1 ON ccc1.id = ccs1.contract_cargo_consignment_id 
INNER JOIN contract_cargo_head cch1 ON cch1.id = ccc1.contract_cargo_head_id 
INNER JOIN contract c1 ON c1.id = cch1.contract_id 
WHERE cch1.cargo_id = 2616
AND pcc1.placement_id = 46 
AND c1.contragent_id = 50
AND cry1.remains_time = (SELECT MAX(cry3.remains_time) 
 						              FROM cargo_remains cry3 
                           WHERE cry3.cargo_card_id = cc1.id 
                           AND cry3.cargo_card_id = cry1.cargo_card_id 
                           AND (cry3.remains_time <= :remains_time_yesterday))
...
Рейтинг: 0 / 0
11.11.2016, 13:40
    #39345575
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
svnvlad,

Показывайте план запроса.
...
Рейтинг: 0 / 0
11.11.2016, 14:14
    #39345616
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
miksoft,

как показать?
...
Рейтинг: 0 / 0
11.11.2016, 14:33
    #39345638
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
Уйди от подзапроса во where, добавь ещё одну таблицу в источник, а отбор максимального замени на сортировку и лимитирование.
...
Рейтинг: 0 / 0
11.11.2016, 14:40
    #39345648
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
AkinaУйди от подзапроса во where, добавь ещё одну таблицу в источник, а отбор максимального замени на сортировку и лимитирование.
Где-то здесь была целая статья про отбор максимального. Почему же там нет ни одного примера с сортировкой и лимитированием?
...
Рейтинг: 0 / 0
11.11.2016, 14:52
    #39345667
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
svnvladПочему же там нет ни одного примера с сортировкой и лимитированием?Потому что решается задача отбора для группы, а не по всему массиву.
...
Рейтинг: 0 / 0
11.11.2016, 15:18
    #39345705
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
AkinasvnvladПочему же там нет ни одного примера с сортировкой и лимитированием?Потому что решается задача отбора для группы, а не по всему массиву.
Ну полный запрос вот так выглядит
Код: 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.
SELECT cn.id, pcc.placement_id, ca.id, cargo_id, cargo_nomenclature_name, ca.contragent_full_name AS cargo_owner_name, placement_number, 
(CASE `c`.`cargo_status` 
WHEN 'export' THEN CONCAT(`cn`.`cargo_nomenclature_name`,' (Э)') 
WHEN 'import' THEN CONCAT(`cn`.`cargo_nomenclature_name`,' (И)') 
WHEN 'domestic' THEN CONCAT(`cn`.`cargo_nomenclature_name`,' (К)') 
ELSE `cn`.`cargo_nomenclature_name` end) AS cargo_nom_rus,

(SELECT SUM(cry1.weight_brutto_remains)
/*(SELECT cry1.weight_brutto_remains */
FROM cargo_remains cry1 
INNER JOIN cargo_card cc1 ON cc1.id = cry1.cargo_card_id 
INNER JOIN placement_cargo_card pcc1 ON pcc1.id = cc1.id 
INNER JOIN contract_cargo_sub ccs1 ON ccs1.id = cc1.contract_cargo_sub_id 
INNER JOIN contract_cargo_consignment ccc1 ON ccc1.id = ccs1.contract_cargo_consignment_id 
INNER JOIN contract_cargo_head cch1 ON cch1.id = ccc1.contract_cargo_head_id 
INNER JOIN contract c1 ON c1.id = cch1.contract_id 
WHERE cch1.cargo_id = cch.cargo_id 
AND pcc1.placement_id = pcc.placement_id 
AND c1.contragent_id = c.contragent_id 
AND cry1.remains_time = (SELECT MAX(cry3.remains_time) 
 						              FROM cargo_remains cry3 
                           WHERE cry3.cargo_card_id = cc1.id 
                           AND cry3.cargo_card_id = cry1.cargo_card_id 
                           AND (cry3.remains_time <= :remains_time_yesterday))) AS brutto_remains_sum_y 


FROM cargo_card cc 
INNER JOIN placement_cargo_card pcc ON pcc.id = cc.id 
INNER JOIN placement p ON p.id = pcc.placement_id 
INNER JOIN cargo_zone z ON z.id = p.cargo_zone_id 
INNER JOIN contract_cargo_sub ccs ON ccs.id = cc.contract_cargo_sub_id 
INNER JOIN contract_cargo_consignment ccc ON ccc.id = ccs.contract_cargo_consignment_id 
INNER JOIN contract_cargo_head cch ON cch.id = ccc.contract_cargo_head_id 
INNER JOIN contract c ON c.id = cch.contract_id 
INNER JOIN contragent ca ON ca.id = c.contragent_id 
INNER JOIN cargo_nomenclature cn ON cn.id = cch.cargo_id 
AND p.cargo_zone_id = :cargo_zone_id
GROUP BY cn.id, pcc.placement_id, ca.id
ORDER BY cargo_nomenclature_name, ca.contragent_full_name, placement_number
...
Рейтинг: 0 / 0
11.11.2016, 15:22
    #39345710
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
miksoftsvnvlad,

Показывайте план запроса.
Вот план запроса. Что он дает?
...
Рейтинг: 0 / 0
11.11.2016, 15:35
    #39345731
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
AkinaУйди от подзапроса во where, добавь ещё одну таблицу в источник, а отбор максимального замени на сортировку и лимитирование.
Не совсем понял, как уйти от подзапроса и что значит добавить еще одну таблицу в источник?
...
Рейтинг: 0 / 0
12.11.2016, 05:23
    #39346013
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
Переписал подзапрос вместо MAX на LIMIT 1, результат точно такой же - 219 мс.
Код: sql
1.
2.
3.
4.
SELECT MAX(cry3.remains_time) 
    FROM cargo_remains cry3 
    WHERE cry3.cargo_card_id = 79530
    AND (cry3.remains_time <= :remains_time_yesterday)



Код: sql
1.
2.
3.
4.
5.
6.
SELECT cry3.remains_time
    FROM cargo_remains cry3 
    WHERE cry3.cargo_card_id = 79530
    AND (cry3.remains_time <= :remains_time_yesterday)
    ORDER BY cry3.`remains_time` DESC
    LIMIT 1
...
Рейтинг: 0 / 0
12.11.2016, 05:30
    #39346014
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
Также нашел лишний AND в подзапросе. Убрал, общее время большого запроса сократилось с 4 минут до 13 секунд. Но все равно много, потому что на самом деле там скалярных подзапросов в самом болшом запросе не 1, а около 10.
...
Рейтинг: 0 / 0
12.11.2016, 14:03
    #39346085
Злой Бобр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
svnvlad,

INNER JOIN замени на LEFT JOIN
...
Рейтинг: 0 / 0
14.11.2016, 08:15
    #39346576
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
Злой Бобрsvnvlad,

INNER JOIN замени на LEFT JOIN
Зачем? Inner же быстрее.
...
Рейтинг: 0 / 0
14.11.2016, 08:40
    #39346584
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
Злой Бобрsvnvlad,

INNER JOIN замени на LEFT JOIN
Заменил. Запрос вместо 14 секунд стал выполняться за 20 и более минут (не дождался).
...
Рейтинг: 0 / 0
14.11.2016, 09:01
    #39346591
svnvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
Как в EMS MySQL Manager-е посмотреть план запроса? Похоже то, что он выдает как план, это совершенно не то, что нужно. Там нет времени выполнения.
...
Рейтинг: 0 / 0
14.11.2016, 14:46
    #39346888
netwind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
svnvlad, а никак.
в оригинале план взятый из команды explain не показывает время выполнения запроса. нужно два раза запускать один раз для плана, второй раз для измерения.
ems вообще какие-то поверхностные программы выпускает для всех субд сразу.
используйте dbforge
...
Рейтинг: 0 / 0
16.11.2016, 05:51
    #39348014
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
svnvladЗапрос выполняется очень медленно. Это внутренняя часть, выделенная из общего запроса, и она выдает 2 записи и выполняется 2 секунды. Полный запрос, в котором 400 записей, соответственно, выполняется 4 минуты.
Как оптимизировать запрос? Можно ли переписать на Join?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT cry1.weight_brutto_remains 
FROM cargo_remains cry1 
INNER JOIN cargo_card cc1 ON cc1.id = cry1.cargo_card_id 
INNER JOIN placement_cargo_card pcc1 ON pcc1.id = cc1.id 
INNER JOIN contract_cargo_sub ccs1 ON ccs1.id = cc1.contract_cargo_sub_id 
INNER JOIN contract_cargo_consignment ccc1 ON ccc1.id = ccs1.contract_cargo_consignment_id 
INNER JOIN contract_cargo_head cch1 ON cch1.id = ccc1.contract_cargo_head_id 
INNER JOIN contract c1 ON c1.id = cch1.contract_id 
WHERE cch1.cargo_id = 2616
AND pcc1.placement_id = 46 
AND c1.contragent_id = 50
AND cry1.remains_time = (SELECT MAX(cry3.remains_time) 
 						              FROM cargo_remains cry3 
                           WHERE cry3.cargo_card_id = cc1.id 
                           AND cry3.cargo_card_id = cry1.cargo_card_id 
                           AND (cry3.remains_time <= :remains_time_yesterday))




вообше долно быстро работать ...ну если на каждом
жоинте не много детишек и индексы на месте.
Судя по плану, вроде бы все ок, но 2 секунды это
ни в какие ворота...
Когда много жоинтов, оптимизатор может запутаться.

Варинаты:

1. обновите статистики, проверьте на другом сервере, другой версии.
т.е. убедитесь что проблема не зависит (или зависит?) от фаз луны...

2. начните собирать запрос с начала -- cch1, потом c1.
то есть в порядке как в ЕХПЛАИН. Это не обязательно самый оптимальный
порядок но для первого проближения сойдет.
Меряйте время -- на каком то этапе время прыгнет с 2 милисекунд до 200 милисекунд
вот тут то и ловите ЕХПЛАИН. Возможно увидете как изменился порядок
таблиц в ЕХПЛАИН. есть возможность закрепить порядок
но это только после исследования...

3. Успехов :-)
...
Рейтинг: 0 / 0
16.11.2016, 11:05
    #39348179
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорить запрос
[quot svnvlad]Запрос выполняется очень медленно. Это внутренняя часть, выделенная из общего запроса, и она выдает 2 записи и выполняется 2 секунды. Полный запрос, в котором 400 записей, соответственно, выполняется 4 минуты.
Как оптимизировать запрос?


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


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