Сравнение группы по Vs через разделение
-
27-10-2019 - |
Вопрос
Предполагая одну таблицу CAR
с двумя столбцами CAR_ID (int)
а также VERSION (int)
.
Я хочу получить максимальную версию каждого автомобиля.
Итак, есть два решения (по крайней мере):
select car_id, max(version) as max_version
from car
group by car_id;
Или же :
select car_id, max_version
from ( select car_id, version
, max(version) over (partition by car_id) as max_version
from car
) max_ver
where max_ver.version = max_ver.max_version
Эти два запроса одинаково исполняют?
Решение
Да, это может повлиять
Второй запрос является примером встроенного представления. Это очень полезный метод для выполнения отчетов с различными типами подсчета или использованием любых агрегатных функций с ним.
Oracle выполняет подбору, а затем использует полученные ряды в качестве представления в предложении FROD.
Как мы рассматриваем о производительности, всегда рекомендуйте Inline View вместо выбора другого типа подказки.
И еще одна второй запрос даст все записи Max, в то время как первый даст вам только одну Max Record.
Другие советы
Я знаю, что это очень старое, но думал, что это следует указать.
select car_id, max_version
from (select car_id
, version
, max(version) over (partition by car_id) as max_version
from car ) max_ver
where max_ver.version = max_ver.max_version
Не уверен, почему вы сделали вариант второй ... в этом случае Sub Select должен быть теоретически медленнее, потому что вы выбираете из одной таблицы 2x, а затем присоединяется к результатам к себе.
Просто удалите версию из вашего встроенного представления, и они одно и то же.
select car_id, max(version) over (partition by car_id) as max_version
from car
Производительность действительно зависит от оптимизатора в этой ситуации, но да, оригинальный ответ предлагает встроенные представления, поскольку они дают узкие результаты. Хотя это не очень хороший пример - это та же таблица без фильтров в приведенных выборах.
Разделение также полезно, когда вы выбираете много столбцов, но нуждаются в разных агрегациях, которые соответствуют набору результатов. В противном случае вы вынуждены группироваться по любым другим столбцам.
Это будет зависеть от вашей схемы индексации и объема данных в таблице. Оптимизатор, вероятно, будет принимать различные решения на основе данных, которые на самом деле находятся внутри таблицы.
Я обнаружил, по крайней мере, в SQL Server (я знаю, что вы спросили об Oracle), что оптимизатор с большей вероятностью выполнит полное сканирование с разделом «Запрос против группы». Но это только в тех случаях, когда у вас есть индекс, который содержит в нем CAR_ID и версию (DESC).
Мораль этой истории в том, что я бы тщательно проверил, чтобы выбрать правильный. Для маленьких столов это не имеет значения. Для действительно, действительно больших наборов данных, ни один из них не может быть быстрым ...