Аналитическая функция Oracle в течение минуты оценивает в группировке

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

7
задан APC 15 April 2013 в 02:14
поделиться

4 ответа

Я думаю, что функция Rank () не подходит для этого по двум причинам.

Во-первых, она, вероятно, менее эффективна, чем метод, основанный на Min ().

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

Таким образом, производительность функции Rank () зависит от общее количество элементов, которые нужно просканировать, и если их достаточно, чтобы сортировка попала на диск, производительность упадет.

Это, вероятно, более эффективно:

select dept,
       emp,
       salary
from
       (
       SELECT dept, 
              emp,
              salary,
              Min(salary) Over (Partition By dept) min_salary
       FROM   mytable
       )
where salary = min_salary
/

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

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

Вторая причина, почему Rank () не нравится, состоит в том, что она просто отвечает на неправильный вопрос. Вопрос не в том, «Какие записи имеют зарплату, которая является первой в рейтинге, когда зарплаты по отделам упорядочены по возрастанию», а в том, «Какие записи имеют минимальную зарплату по отделам».

9
ответ дан 6 December 2019 в 14:06
поделиться

Вы можете использовать синтаксис RANK () . Например, этот запрос скажет вам, какое место занимает сотрудник в своем отделе с учетом размера его зарплаты:

SELECT
  dept,
  emp,
  salary,
  (RANK() OVER (PARTITION BY dept ORDER BY salary)) salary_rank_within_dept
FROM EMPLOYEES

Затем вы можете запросить отсюда, где salary_rank_within_dept = 1 :

SELECT * FROM
  (
    SELECT
      dept,
      emp,
      salary,
      (RANK() OVER (PARTITION BY dept ORDER BY salary)) salary_rank_within_dept
    FROM EMPLOYEES
  )
WHERE salary_rank_within_dept = 1
3
ответ дан 6 December 2019 в 14:06
поделиться
select e2.dept, e2.emp, e2.salary
from employee e2
where e2.salary = (select min(e1.salary) from employee e1)
-1
ответ дан 6 December 2019 в 14:06
поделиться

Я думаю, вы довольно близко подошли к своему первоначальному запросу. Следующее будет работать и соответствовать вашему тесту:

SELECT dept, 
  MIN(emp) KEEP(DENSE_RANK FIRST ORDER BY salary, ROWID) AS emp,
  MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY salary, ROWID) AS salary
FROM mytable
GROUP BY dept

В отличие от решений RANK (), это гарантирует не более одной строки на отдел. Но это намекает на проблему: что происходит в отделе, где два сотрудника получают самую низкую зарплату? Решения RANK () вернут обоих сотрудников - более одной строки для отдела. В этом ответе будет выбрано одно произвольно, и убедитесь, что для отдела есть только один.

4
ответ дан 6 December 2019 в 14:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: