Вдохновленный этим вопросом Я решил протестировать функцию rank()
, пытаясь определить, являются ли подзапросы менее эффективными, чем рейтинг. Итак, я создал таблицу:
create table teste_rank ( codigo number(7), data_mov date, valor number(14,2) );
alter table teste_rank add constraint tst_rnk_pk primary key ( codigo, data_mov );
и вставил несколько записей ...
declare
vdata date;
begin
dbms_random.initialize(120401);
vdata := to_date('04011997','DDMMYYYY');
for reg in 1 .. 465 loop
vdata := to_date('04011997','DDMMYYYY');
while vdata <= trunc(sysdate) loop
insert into teste_rank
(codigo, data_mov, valor)
values
(reg, vdata, dbms_random.value(1,150000));
vdata := vdata + 2;
end loop;
commit;
end loop;
end;
/
А затем проверил два запроса:
select *
from teste_rank r
where r.data_mov = ( select max(data_mov)
from teste_rank
where data_mov <= trunc(sysdate)
and codigo = 1 )
and r.codigo = 1;
select *
from ( select rank() over ( partition by codigo order by data_mov desc ) rn, t.*
from teste_rank t
where codigo = 1
and data_mov <= trunc(sysdate) ) r
where r.rn = 1;
Как видите, стоимость подзапроса ниже, чем rank (). Это правильно? Я что-то там упускаю?
PS: протестировано также с полным запросом в таблице и по-прежнему подзапросом с низкой стоимостью.
EDIT
Я сгенерировал tkprof из двух запросов (отслеживаемый, закрытие базы данных, запуск и отслеживание второго).
Для подзапроса
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.02 3 5 0 0
Execute 1 0.00 0.00 0 3 0 0
Fetch 2 0.00 0.00 1 4 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.02 4 12 0 1
Для rank()
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.02 3 3 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 9 19 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.01 0.03 12 22 0 1
Можно ли сделать вывод, что подзапрос не всегда будет менее эффективным, чем рейтинг? Когда указывается ранг вместо подзапроса?