Есть запрос SQL, проблемная часть которого выглядит так:
SELECT DISTINCT chb.ck_filename,
...
(select gvpl.gvpl_descr
from gviya gv1, gviya_place gvpl
where gv1.gv_gvpl_id = gvpl.gvpl_id
and gv1.gv_id = (select max(gviya.gv_id)
from gviya
where gv_trid = chb.ck_trid
)
) as gv_place,
...
Дальше идет выборка остальных полей. Так как в таблице очень много данных, то вложенный запрос выполняется очень долго. Понятно, что он должен выполниться для каждой строчки, то есть, допустим, если основной запрос вернет 1000 строчек, то и вложенный выполнится 1000 раз, увеличивая общее время выполнения в 1000 раз. Надо как-то избавиться от вложенного запроса, при этом все равно получая gvpl_descr
для max(gviya.gv_id)
в каждой строчке. Спасибо за ответы.
Ну, можно начать с самого "нижнего" подзапроса, группировать его
select max(gviya.gv_id)
from gviya
group by gv_trid
Затем его присоединить к вышестоящему запросу
select gvpl.gvpl_descr
from gviya gv1, gviya_place gvpl,
(select gv_trid, max(gviya.gv_id) max_gv_id
from gviya
group by gv_trid) group_gviya
where gv1.gv_gvpl_id = gvpl.gvpl_id
and group_gviya.gv_trid = chb.ck_trid
and gv1.gv_id = group_gviya.max_gv_id
Либо можно, наверное, попробовать как-то воспользоваться оконными функциями
Можно переписать подзапрос в виде:
select gvpl.gvpl_descr
from gviya gv1, gviya_place gvpl
where gv1.gv_gvpl_id = gvpl.gvpl_id
and gv_trid = chb.ck_trid
order by gv1.gv_id desc
limit 1
Таким образом мы избавимся от подзапроса второго уровня. Но его выполнение все равно будет достаточно медленным. В идеале надо избавится вообще от подзапросов в списке выборки, например сгруппировав и заранее получив все максимальные gv_id, как предложено в ответе @Vasil Baymurzin. Но такой подход даст существенный выигрыш только если весь целый запрос выбирает бОльшую часть всех существующих gv_trid. Если это не так, надо смотреть в сторону обеспечения получения уникальных строк всего запроса, а потом подклейки к ним (join) всех подходящих строк gviya с последующей фильтрацией на максимальные с помощью использования переменных или трюков вроде substr( max( concat() ) )
, как предложено например тут.
В общем для правильной оптимизации, информации, приведенной в вопросе, не достаточно. Необходимо видеть в комплексе весь запрос, всю структуру БД, смотреть планы выполнения и экспериментировать.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как получить скриншот всей структуры дерева TreeView? Делал это следующим кодом, но он получает изображение только видимой области дерева:
Есть json, для которого Visual Studio сгенерировал вот такой класс