02.11.2011

INNER JOIN или WHERE?

Проверим с помощью пакета RUNSTATS, насколько отличаются затраты на оба подхода.
Создадим и заполним таблицы
create table i1(
n number primary key,
v varchar2(10)
);
create table i2(
n number primary key,
v varchar2(10)
);
/
INSERT INTO i1
SELECT rownum, rpad('-',10,'-') FROM all_objects;
dbms_output.put_line('Added: ' || sql%rowcount);
INSERT INTO i2
SELECT rownum, rpad('-',10,'-') FROM all_objects;
dbms_output.put_line('Added: ' || sql%rowcount);
---------
Added: 56372
Added: 56372
Выполним:
declare
-- Local variables here
i integer;
begin
ALEX.P_RUNSTATS.rs_start;
select count(*) into i from i1, i2 where i1.n = i2.n;
ALEX.P_RUNSTATS.rs_middle;
select count(*) into i from i1 inner join i2 on i1.n = i2.n;
ALEX.P_RUNSTATS.rs_stop;
end;
Результат:
Run1 ran in 17 hsecs
Run2 ran in 21 hsecs
run 1 ran in 80,95% of the time
-------
Name                                Run1      Run2      Diff
STAT...db block changes               34        35         1
STAT...consistent gets from ca    56,499    56,498        -1
STAT...heap block compress             6         7         1
STAT...session logical reads      56,522    56,523         1
STAT...free buffer requested           0         1         1
LATCH.undo global data                 7         6        -1
LATCH.redo allocation                 12        11        -1
STAT...consistent gets            56,499    56,498        -1
STAT...db block gets from cach        23        25         2
STAT...db block gets                  23        25         2
LATCH.ASM db client latch              0         2         2
LATCH.enqueue hash chains              0         2         2
LATCH.enqueues                         0         2         2
LATCH.redo writing                     0         2         2
LATCH.object queue header oper         0         2         2
LATCH.messages                         0         4         4
STAT...undo change vector size     2,220     2,224         4
STAT...recursive cpu usage            23        27         4
STAT...CPU used by this sessio        23        27         4
LATCH.ASM map operation hash t         0         6         6
LATCH.channel operations paren         0         9         9
LATCH.cache buffers chains        56,742    56,729       -13
LATCH.checkpoint queue latch           0        32        32
STAT...redo size                   3,012     3,076        64
LATCH.SQL memory manager worka         6        73        67
----------
Run1 latches total versus runs -- difference and pct
Run1      Run2      Diff     Pct
66,549    66,662       113  99.83%
Видим, что разница в затратах крайне мала. Может быть, что-то изменится от количества связываемых таблиц?
declare
-- Local variables here
i integer;
begin
ALEX.P_RUNSTATS.rs_start;
select count(*)
into i
from i1 a1, i1 a2, i1 a3, i1 a4, i2 b1, i2 b2, i2 b3, i2 b4
where a1.n = a2.n
and a2.n = a3.n
and a3.n = a4.n
and b1.n = a1.n
and b1.n = b2.n
and b3.n = b2.n
and b4.n = b3.n;
ALEX.P_RUNSTATS.rs_middle;
select count(*)
into i
from i1 a1
inner join i1 a2 on a1.n = a2.n
inner join i1 a3 on a2.n = a3.n
inner join i1 a4 on a3.n = a4.n
inner join i2 b1 on b1.n = a1.n
inner join i2 b2 on b2.n = b1.n
inner join i2 b3 on b3.n = b2.n
inner join i2 b4 on b4.n = b3.n;
ALEX.P_RUNSTATS.rs_stop;
end;
Результат (показатели несущественно различаются, приведу только количество блокировок):
Run1 latches total versus runs -- difference and pct
Run1      Run2      Diff     Pct
463,297   463,132      -165 100.04%

Естественно, с ростом числа таблиц возросло и количество блокировок, но их соотношение между запросами осталось крайне мало.
Вывод: запросы практически одинаковы по затратам (но мне как-то ближе связывание по условиям).

Комментариев нет :