我有一个SQL语句,在PL / SQL块中执行时会产生明显不同的性能。
SQL非常简单。
INSERT into Existing_Table SELECT col1,col2... from Other_table where rownum < 100000
当它作为SQL执行时,它几乎立即返回。
但是当在Anonymous PL / SQL块中执行时,它会永远挂起:
begin
INSERT into Existing_Table SELECT col1, col2... from Other_table where rownum < 100000;
end;
/
答案 0 :(得分:2)
但是当在Anonymous PL / SQL块中执行时,它会永远挂起:
我猜两件事:
在SQL和PL / SQL中执行语句不应该在性能上有所不同。它应该在几乎相同的时间内执行。 但由于约束或提交,它被阻止,因为该行被锁定。
这是一个例子。
在第1节中,创建两个表。一个有约束,一个没有:
create table Existing_Table
(
existing_column number primary key
);
create table Existing_Table_2
(
existing_column number
);
在同一会话中,执行以下SQL语句:
insert into Existing_Table (existing_column) values (1);
结果:
1 row inserted.
在另一个(会话2)上,执行以下PL / SQL匿名阻止:
begin
insert into Existing_Table (existing_column) values (1);
end;
这将挂起,直到您在会话1中发出提交。
这是因为第1节已经&#34;保留&#34; &#34; 1&#34;的价值对于existing_column,将被&#34;保存&#34;当您发出提交时。 第2节仅仅是等待会话1提交或回滚插入。
现在,当我回到会话1并发出提交时,该行将被解锁。 但是,由于完整性约束违规,会话2将导致错误:
Error starting at line : 1 in command -
begin
insert into Existing_Table (existing_column) values (1);
end;
Error report -
ORA-00001: unique constraint (APPS.SYS_C001730810) violated
ORA-06512: at line 2
00001. 00000 - "unique constraint (%s.%s) violated"
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action: Either remove the unique restriction or do not insert the key.
现在,另一个没有约束的表的例子。
在会话3中运行以下SQL而不提交:
insert into Existing_Table_2 (existing_column) values (1);
结果:
1 row inserted.
在会话4中的匿名PL / SQL块中运行相同的SQL:
begin
insert into Existing_Table_2 (existing_column) values (1);
end;
结果:
PL/SQL procedure successfully completed.
即使没有在会话1中提交,它也会插入正常,因为没有违反任何约束。
请注意,在您发出提交之前,会话3和4中的所有数据都不会实际保存在数据库中。
在此处查看有关会话阻止的其他文章:
答案 1 :(得分:0)
我试图重新创建问题,但无法解决。正如其他人正确指出的那样,SQL很简单并且执行它,因为SQL或者不是PL / SQL就不应该有所不同。
我唯一想到的是,我可能没有注意到是否有另一个会话在没有COMMIT / ROLLBACK的情况下尝试DML;这可能导致了悬念。所以BobC和Migs Isip提到的场景可能与此相关。谢谢大家。