Группа сравнения по VS Over Partition By - PullRequest
4 голосов
/ 17 февраля 2012

Предполагая одну таблицу 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

Являются ли эти два запроса одинаково эффективными?

Ответы [ 3 ]

3 голосов
/ 02 октября 2015

Я знаю, что это очень старо, но подумал, что на это нужно указать.

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

Не уверен, почему вы сделали второй вариант таким образом ... в этом случае подвыбор должен быть теоретически медленнее, потому что вы выбираете из той же таблицы 2x и затем объединяете результаты обратно к себе.

Просто удалите версию из встроенного представления, и это одно и то же.

select car_id, max(version) over (partition by car_id) as max_version
  from car

Производительность действительно зависит от оптимизатора в этой ситуации, но да, как и в оригинальном ответе, предлагаются встроенные представления, поскольку они дают узкие результаты. Хотя это не очень хороший пример, это та же самая таблица без фильтров в выбранных выборках.

Секционирование также полезно, когда вы выбираете много столбцов, но нуждаетесь в разных агрегатах, которые соответствуют результирующему набору. В противном случае вы вынуждены группировать по каждому другому столбцу.

3 голосов
/ 17 февраля 2012

Да Может влиять

Второй запрос является примером встроенного просмотра. Это очень полезный метод для выполнения отчетов с различными типами подсчетов или для использования с ними каких-либо агрегатных функций.

Oracle выполняет подзапрос, а затем использует полученные строки как представление в предложении FROM.

Поскольку мы учитываем производительность, всегда рекомендуем встроенное представление вместо выбора другого типа подзапроса.

И еще один второй запрос даст все максимальные записи, тогда как первый даст вам только одну максимальную запись.

см. Здесь

2 голосов
/ 17 февраля 2012

Это будет зависеть от вашей схемы индексации и количества данных в таблице.Оптимизатор, скорее всего, будет принимать разные решения на основе данных, которые на самом деле находятся внутри таблицы.

Я обнаружил, по крайней мере в SQL Server (я знаю, что вы спрашивали об Oracle), что оптимизатор с большей вероятностью выполнит полное сканирование с помощью запроса PARTITION BY по сравнению с запросом GROUP BY.Но это только в тех случаях, когда у вас есть индекс, содержащий CAR_ID и VERSION (DESC).

Мораль этой истории в том, что я тщательно проверю, чтобы выбрать правильный.Для небольших столов это не имеет значения.Для действительно очень больших наборов данных ни один не может быть быстрым ...

...