Oracle优化查询避免使用游标
我正在开发一个我想要优化的sql。 我有一堆游标。 我想知道我是否可以用别的东西代替光标。 我在考虑使用一些变量,填充它们,在剩下的处理中避免DB连接(我有一个复杂的处理) 例如,我有一段代码,如:Oracle优化查询避免使用游标,oracle,cursors,Oracle,Cursors,我正在开发一个我想要优化的sql。 我有一堆游标。 我想知道我是否可以用别的东西代替光标。 我在考虑使用一些变量,填充它们,在剩下的处理中避免DB连接(我有一个复杂的处理) 例如,我有一段代码,如: TYPE rec_basket IS RECORD ( FIELD1 VARCHAR2(40), FIELD2 NUMBER(10), FIELD3 VARCHAR2(6) ); TYPE tab_basket IS TABLE OF rec_basket INDEX BY BINAR
TYPE rec_basket IS RECORD (
FIELD1 VARCHAR2(40),
FIELD2 NUMBER(10),
FIELD3 VARCHAR2(6)
);
TYPE tab_basket IS TABLE OF rec_basket
INDEX BY BINARY_INTEGER;
CURSOR cur_baskets
IS
select * from toto
FOR i IN cur_baskets
LOOP
l_tab_basket (l_nbasket).field1 := i.field1;
l_tab_basket (l_nbasket).field2 := i.field2;
l_tab_basket (l_nbasket).field3 := i.field3;
l_nbasket := l_nbasket + 1;
END LOOP;
CURSOR cur_baskets
IS
select * from toto
FOR i IN cur_baskets
LOOP
l_tab_basket (l_nbasket).field1 := i.field1;
l_tab_basket (l_nbasket).field2 := i.field2;
l_tab_basket (l_nbasket).field3 := i.field3;
l_nbasket := l_nbasket + 1;
END LOOP;
使用光标并填充l_tab_basket变量是最好的方法吗?我在代码中的某个地方使用了l\u tab\u basket(索引)。
我之所以使用这段代码,是因为我想对其他游标使用这种机制。
实际上,我有一个光标在另一个里面。对于每一行我都有一些治疗。我想用别的东西来代替光标,但我不知道怎么做。
谢谢。您可以使用批量收集将所有记录提取到嵌套表中。这将在10g+中工作:
SQL> DECLARE
2 TYPE rec_basket IS RECORD(
3 field1 VARCHAR2(40),
4 field2 NUMBER(10),
5 field3 VARCHAR2(6));
6 TYPE tab_basket IS TABLE OF rec_basket INDEX BY BINARY_INTEGER;
7 l_tab_basket tab_basket;
8 BEGIN
9 SELECT 'a', ROWNUM, 'b'
10 BULK COLLECT INTO l_tab_basket
11 FROM dual CONNECT BY LEVEL <= 1000;
12 END;
13 /
PL/SQL procedure successfully completed
SQL>DECLARE
2类回收篮为记录(
3现场1瓦查尔2(40),
4字段2编号(10),
5个字段3 VARCHAR2(6));
6类tab_篮子是按二进制整数计算的回收篮子索引表;
7 l_tab_basket tab_basket;
8开始
9选择“a”,行数,“b”
10散装收集到l_tab_篮中
11从dual CONNECT BY LEVEL开始,代码的逻辑不是很清楚。您还没有编写整个程序。让我们研究一下:
光标curu_
是
从toto中选择*
在这里,从表toto中读取值并将其放入光标中
在以下几行中,从光标读取值并放入l_tab_篮中
因为我把钱放在篮子里
环
l_tab_basket(l_nbasket).field1:=i.field1;
l_tab_basket(l_nbasket).field2:=i.field2;
l_tab_basket(l_nbasket).field3:=i.field3;
l_nbasket:=l_nbasket+1
端环
所以,相同的值将两次传递给局部变量。这是可以避免的。您可以找到直接插入或更新目标表的方法
你可以尝试批量收集。如果toto很小,您可以在不使用游标的情况下插入或更新目标表。我们需要更多上下文-我认为不需要游标或用户定义的类型,只需要一个派生表/内联视图,但我不知道它的用途。上下文同上。这个过程应该是什么,需要多长时间,以及对持续时间的主要贡献。我认为Oracle只对隐式游标“提前获取”,我需要的是能够从我的tab_篮中一行一行地检索。我该怎么做?@CC-为什么你认为你需要一个接一个地检索记录?集合处理无疑是处理数据的最佳方式。你真的需要给我们更多的细节。帮助我们帮助你。我不认为我需要一个接一个地检索记录,我只需要它。每一行我都有一些东西。我有一个光标在另一个里面。我只是想找到优化这些东西的最佳解决方案。@OMG Ponies:你说得对:)看。隐式游标几乎总是优于显式游标,特别是因为Oracle对它们进行了更优化。我不知道最近的版本是否改变了这种行为,但我刚刚用10.2.0.3检查了一下,只有隐式游标可以提前获取。实际上,我使用l_tab_basket是因为我需要多次恢复数据(因为这部分在另一个游标中),以避免多次执行查询。我有两个游标(一个在另一个内)。内部一个有50个项目,外部一个有2000个项目。由于内部一个将在外部一个的每次迭代中执行,所以我使用的表_将值放入一个变量中。感谢插入批量的想法。我完成了任务。@CC不客气。我感谢你的赞扬和评论。