Original bulk collect version.
SQL> create or replace type ns_typ is table of number;
2 /
Type created.
SQL> create or replace function rn(n number) return ns_typ is
2 ret ns_typ;
3 begin
4 dbms_lock.sleep(1);
5 select level bulk collect into ret from dual connect by level <= n;
6 return ret;
7 end;
8 /
Function created.
And the pipelined version of the function.
SQL> create or replace function rnpiped(n number) return ns_typ pipelined is
2 begin
3 for ret in
4 (select level l from dual connect by level <= n)
5 loop
6 dbms_lock.sleep(1/n);
7 pipe row (ret.l);
8 end loop;
9 end;
10 /
If the whole result returned from the function is needed there is no great difference in the execution times. Actually it seems to be increasing a bit.
SQL> select * from table(rn(10));
COLUMN_VALUE
------------
1
2
3
4
5
6
7
8
9
10
10 rows selected.
Elapsed: 00:00:01.00
SQL>
SQL> select * from table(rnpiped(10));
COLUMN_VALUE
------------
1
2
3
4
5
6
7
8
9
10
10 rows selected.
Elapsed: 00:00:01.07
But when used in IN predicate the results with this data are even better than in the previous post.
SQL> select * from ta a where a.n in (select * from table(rn(a.m)));
N M
---------- ----------
1 2
2 3
Elapsed: 00:00:10.00
SQL>
SQL> select * from ta a where a.n in (select * from table(rnpiped(a.m)));
N M
---------- ----------
1 2
2 3
Elapsed: 00:00:01.95
And putting both together.
SQL> with aa as (
2 select *
3 from ta a
4 ), bb as (
5 select distinct m
6 from aa
7 ), cc as (
8 select /*+materialize*/ b.m, dd.column_value n
9 from bb b, table(rn(b.m)) dd)
10 select *
11 from aa
12 where (n,m) in (select n,m from cc)
13 ;
N M
---------- ----------
1 2
2 3
Elapsed: 00:00:03.09
SQL>
SQL> with aa as (
2 select *
3 from ta a
4 ), bb as (
5 select distinct m
6 from aa
7 ), cc as (
8 select /*+materialize*/ b.m, dd.column_value n
9 from bb b, table(rnpiped(b.m)) dd)
10 select *
11 from aa
12 where (n,m) in (select n,m from cc)
13 ;
N M
---------- ----------
1 2
2 3
Elapsed: 00:00:00.68
No comments:
Post a Comment