Plsql函数查询中的性能调优
Performance Tuning In Plsql Function Query
我有 plsql 功能。这个函数有如下查询:
select colum_name
from table_name
where filter_coloumn_name in ( select filter_coloumn_name from table_name_2);
我的函数被其他查询用于 return 来自查询的值。使用此功能的此查询需要更多时间。甚至网站(前台屏幕)也下线了。因为table_name_2有三百万记录。所以我必须在我的函数中使用一些性能调整方法。我更改了我的函数查询,如下所示:
cursor my_cursor IS
select filter_coloumn_name from table_name_2;
TYPE cursor_array_type IS TABLE OF my_cursor%ROWTYPE INDEX BY BINARY_INTEGER;
m cursor_array_type;
TYPE cursor_table_type IS TABLE OF VARCHAR2(20) INDEX BY BINARY_INTEGER;
cursor_table_object cursor_table_type;
fetch_size NUMBER := 5000;
index_var number;
begin
index_var := 1;
open my_cursor;
loop
FETCH my_cursor BULK COLLECT
into m LIMIT fetch_size;
exit when my_cursor %notfound;
for i in 1 .. m.count loop
cursor_table_object (index_var) := m(i).filter_coloumn_name;
index_var := index_var + 1;
end loop;
end loop;
Close my_cursor;
select colum_name
from table_name
where filter_coloumn_name in (cursor_table_object);
select colum_name
from table_name
where filter_coloumn_name in (cursor_table_object);
也就是说,我想一次获取所有值,然后我想像上面那样使用这个 table 对象。但是我不能在 sql 查询的条件表达式中使用 table 对象。
我有 PLS-00382: expression is of wrong type
错误。
我想像下面这样使用这个 table 对象:
select colum_name
from table_name
where filter_coloumn_name in ('bla', 'bla bla', 'bla bla bla');
我应该将 table 对象转换为数组吗?
您必须使用 exists 而不是 in,而且 table_name_2 必须在 filter_coloumn_name 字段上有索引。
只使用游标你得到的是对大 table.
的完全访问
根据您目前所说的内容提出一个建议:使用 table 函数 怎么样?它可以使用您想要使用的语句,即
select colum_name from table_name where filter_coloumn_name in (cursor_table_object);
但是 returns
PLS-00382: expression is of wrong type
这是一个基于 Scott 架构的示例。看看:
SQL> create or replace function f_test
2 return sys.odcinumberlist
3 is
4 -- Cursor's SELECT should contain your 3-million-rows table
5 cursor cur_r is select deptno from dept where deptno < 30;
6 l_ret sys.odcinumberlist;
7 begin
8 open cur_r;
9 fetch cur_r bulk collect into l_ret;
10 close cur_r;
11 return l_ret;
12 end;
13 /
Function created.
SQL> -- How to use it?
SQL> select e.ename
2 from emp e join table(f_test) x on x.column_value = e.deptno;
ENAME
----------
MILLER
KING
CLARK
ADAMS
SCOTT
FORD
JONES
SMITH
8 rows selected.
SQL>
我有 plsql 功能。这个函数有如下查询:
select colum_name
from table_name
where filter_coloumn_name in ( select filter_coloumn_name from table_name_2);
我的函数被其他查询用于 return 来自查询的值。使用此功能的此查询需要更多时间。甚至网站(前台屏幕)也下线了。因为table_name_2有三百万记录。所以我必须在我的函数中使用一些性能调整方法。我更改了我的函数查询,如下所示:
cursor my_cursor IS
select filter_coloumn_name from table_name_2;
TYPE cursor_array_type IS TABLE OF my_cursor%ROWTYPE INDEX BY BINARY_INTEGER;
m cursor_array_type;
TYPE cursor_table_type IS TABLE OF VARCHAR2(20) INDEX BY BINARY_INTEGER;
cursor_table_object cursor_table_type;
fetch_size NUMBER := 5000;
index_var number;
begin
index_var := 1;
open my_cursor;
loop
FETCH my_cursor BULK COLLECT
into m LIMIT fetch_size;
exit when my_cursor %notfound;
for i in 1 .. m.count loop
cursor_table_object (index_var) := m(i).filter_coloumn_name;
index_var := index_var + 1;
end loop;
end loop;
Close my_cursor;
select colum_name
from table_name
where filter_coloumn_name in (cursor_table_object);
select colum_name from table_name where filter_coloumn_name in (cursor_table_object);
也就是说,我想一次获取所有值,然后我想像上面那样使用这个 table 对象。但是我不能在 sql 查询的条件表达式中使用 table 对象。
我有 PLS-00382: expression is of wrong type
错误。
我想像下面这样使用这个 table 对象:
select colum_name
from table_name
where filter_coloumn_name in ('bla', 'bla bla', 'bla bla bla');
我应该将 table 对象转换为数组吗?
您必须使用 exists 而不是 in,而且 table_name_2 必须在 filter_coloumn_name 字段上有索引。 只使用游标你得到的是对大 table.
的完全访问根据您目前所说的内容提出一个建议:使用 table 函数 怎么样?它可以使用您想要使用的语句,即
select colum_name from table_name where filter_coloumn_name in (cursor_table_object);
但是 returns
PLS-00382: expression is of wrong type
这是一个基于 Scott 架构的示例。看看:
SQL> create or replace function f_test
2 return sys.odcinumberlist
3 is
4 -- Cursor's SELECT should contain your 3-million-rows table
5 cursor cur_r is select deptno from dept where deptno < 30;
6 l_ret sys.odcinumberlist;
7 begin
8 open cur_r;
9 fetch cur_r bulk collect into l_ret;
10 close cur_r;
11 return l_ret;
12 end;
13 /
Function created.
SQL> -- How to use it?
SQL> select e.ename
2 from emp e join table(f_test) x on x.column_value = e.deptno;
ENAME
----------
MILLER
KING
CLARK
ADAMS
SCOTT
FORD
JONES
SMITH
8 rows selected.
SQL>