powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Заменить подзапросы JOIN или упростить запрос
9 сообщений из 9, страница 1 из 1
Заменить подзапросы JOIN или упростить запрос
    #39874176
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть запрос в котором помимо данных на период (начало месяца) нужно выбрать еще несколько данных из следующего периода (начало следующего месяца), например:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT account,addr_flat,fio_cur,area_cur,
	(SELECT h_sum_debt FROM data_sgrc WHERE id_contragent=c.id AND period='2018-08-01') AS dh,
	(SELECT hw_sum_debt FROM data_sgrc WHERE id_contragent=c.id AND period='2018-08-01') AS dhw,
	(SELECT h_sum_debt+hw_sum_debt FROM data_sgrc WHERE id_contragent=c.id AND period='2018-08-01') AS dhhw
FROM data_sgrc d 
LEFT JOIN contragents c ON d.id_contragent=c.id 
LEFT JOIN mkd m ON c.id_mkd=m.id 
WHERE m.id=1 AND period='2018-07-01'
ORDER BY dhhw DESC


Вот прямо чувствую, что подзапросы можно убрать, оптимизировав весь запрос, но не могу сообразить как. Помогите, пожалуйста!
...
Рейтинг: 0 / 0
Заменить подзапросы JOIN или упростить запрос
    #39874214
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сделал так, из плана ушли подзапросы:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT account,addr_flat,d.fio_cur,d.area_cur,
		d1.h_sum_debt,d1.hw_sum_debt,d1.h_sum_debt+d1.hw_sum_debt AS dhhw
FROM data_sgrc d 
LEFT JOIN contragents c ON d.id_contragent=c.id 
LEFT JOIN mkd m ON c.id_mkd=m.id 
LEFT JOIN data_sgrc d1 ON d1.id_contragent=c.id AND d1.period='2018-08-01' 
WHERE m.id=1 AND d.period='2018-07-01'
ORDER BY dhhw DESC


Корректно?
...
Рейтинг: 0 / 0
Заменить подзапросы JOIN или упростить запрос
    #39874394
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYingКорректно?Да, вполне. Если не считать того момента, что даже навскидку некоторые LEFT JOIN (первый из трёх - так уж почти наверняка) просто просятся замениться на INNER JOIN.
...
Рейтинг: 0 / 0
Заменить подзапросы JOIN или упростить запрос
    #39874405
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
Все таблицы в запросе связаны посредством primary/foreign ключей, так что Вы, видимо, правы насчет замены на INNER JOIN.
Заменил все LEFT-ы на INNER-ы, вот такой получается explain:
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra LEFT JOIN 1SIMPLEmconstPRIMARYPRIMARY4const1100"Using index; Using temporary; Using filesort"1SIMPLEcrefPRIMARY;fk_mkdfk_mkd5const126100Using index condition1SIMPLEdreffk_contr;i_perfk_contr5direct_contracts.c.id80.57Using where1SIMPLEd1reffk_contr;i_perfk_contr5direct_contracts.c.id8100Using where INNER JOIN 1SIMPLEmconstPRIMARYPRIMARY4const1100"Using index; Using temporary; Using filesort"1SIMPLEcrefPRIMARY;fk_mkdfk_mkd5const126100(Null)1SIMPLEdreffk_contr;i_perfk_contr5direct_contracts.c.id80.57Using where1SIMPLEd1reffk_contr;i_perfk_contr5direct_contracts.c.id80.57Using where
Различие только в filtered и Extra. Не очень понимаю, что оно значит, не поясните?
...
Рейтинг: 0 / 0
Заменить подзапросы JOIN или упростить запрос
    #39874412
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Заменить подзапросы JOIN или упростить запрос
    #39874420
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
:) Не так выразился, описание я читал...
В контексте моего запроса последний INNER получается выгоднее LEFT?
Если rows=8 и filtered=0.57, количество строк, подлежащих соединению со следующей таблицей составляет 8*0.57% = 4,56 для INNER и 8*100% = 800 для LEFT. Этот момент мне не ясен.
...
Рейтинг: 0 / 0
Заменить подзапросы JOIN или упростить запрос
    #39874450
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYingВ контексте моего запроса последний INNER получается выгоднее LEFT?Конечно... Нахрена добавлять пустые записи и обрабатывать потом все записи, когда можно добавить и обработать только имеющие ответную часть?
LiYingЕсли rows=8 и filtered=0.57, количество строк, подлежащих соединению со следующей таблицей составляет 8*0.57% = 4,56 для INNER и 8*100% = 800 для LEFT. Этот момент мне не ясен.По-моему, наоборот - если rows=8 и filtered=0.57, то в таблице всего 8 * 100% / 0,57% ~ 1400 записей, из которых выбираются для дальнейшей обработки только указанные 8.
...
Рейтинг: 0 / 0
Заменить подзапросы JOIN или упростить запрос
    #39874462
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkinaПо-моему, наоборот - если rows=8 и filtered=0.57, то в таблице всего 8 * 100% / 0,57% ~ 1400 записей, из которых выбираются для дальнейшей обработки только указанные 8.
Считал по доку из Вашей ссылки :) Либо у них ошибка в описании:
The filtered column indicates an estimated percentage of table rows that will be filtered by the table condition. The maximum value is 100, which means no filtering of rows occurred. Values decreasing from 100 indicate increasing amounts of filtering. rows shows the estimated number of rows examined and rows × filtered shows the number of rows that will be joined with the following table. For example, if rows is 1000 and filtered is 50.00 (50%), the number of rows to be joined with the following table is 1000 × 50% = 500.
...
Рейтинг: 0 / 0
Заменить подзапросы JOIN или упростить запрос
    #39874470
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да? ну мож и так - я на этот столбец в общем и не смотрю. Всё равно он оценочный, из статистики берётся. Мне как бы использование правильных индексов и время выполнения важнее, чем сомнительные цифири.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Заменить подзапросы JOIN или упростить запрос
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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