【发布时间】:2018-09-20 12:57:06
【问题描述】:
我遇到了性能问题。
第一个 PL/SQL(大多数时间永远不会结束,操作系统数据库进程总是超过 90%):
DECLARE
myId nvarchar2(10) := '0;WF21izb0';
BEGIN
insert into MY_TABLE (select * from MY_VIEW where ID = myId);
END;
第二次PL/SQL(以50s成功结束):
BEGIN
insert into MY_TABLE (select * from MY_VIEW where ID = '0;WF21izb0');
END;
select count(*) from MY_VIEW
也是一个不结束的调用,这个视图后面有很多表连接。
select count(*) from MY_VIEW where ID = '0;WF21izb0'
以 50 秒结束,count=60000。
有人能解释一下为什么我的第一个 PL/SQL 在 50 多岁之后还没有完成吗?使用静态字符串和声明参数有什么区别?
【问题讨论】:
-
我建议您跟踪它,然后分析跟踪文件。您可能会遇到数十人说执行计划不同,但他们只是受过高度教育的猜测。如果您养成正确查看的习惯(trace + profile),那么您将能够更快地解决问题。
-
视图下的表的统计信息是否是最新的?
SELECT LAST_ANALYZED, NUM_ROWS FROM DBA_TABLES WHERE TABLE_NAME = 'YOUR_TABLE_NAME_HERE',并将NUM_ROWS与SELECT COUNT(*) FROM YOUR_TABLE_NAME_HERE进行比较。如果 LAST_ANALYZED 为 NULL 或过期,或者 NUM_ROWS 与实际行数有显着差异,请使用 DBMS_STATS.GATHER_TABLE_STATS 分析表。 -
我不确定@jeff6times7 是否会将其视为一个受过高度教育的猜测,但似乎(1)您的视图投射了大量的行,并且(2)存在巨大的偏差
ID的卷。给定ID的文字值,优化器可以提出一个自定义计划来获取这些记录。但是给定一个盲变量,它使用它已经拥有的任何计划:该计划可能会针对ID的值进行优化,它返回两行;这可能并不明显,但对于返回 60000 行的ID而言,该计划可能是毁灭性的。 -
您可以询问您的 DBA,
cursor_sharing参数是否等于Exact..?
标签: oracle plsql query-performance