如何为oracle循环生成执行计划

时间:2010-12-22 17:05:04

标签: oracle loops sql-execution-plan

如何为oracle循环查询生成执行计划,如下所示:

BEGIN 
  FOR L IN (SELECT FIRST_NAME, LAST_NAME, SOME_ID FROM TABLE1)
  LOOP
      INSERT INTO TABLE2 (FIRSTNAME, LASTNAME)
      (SELECT FNAME, LASTNAME FROM TABLE2 WHERE SOME_ID = L.SOME_ID)

  V_CNT := V_CNT + 1;

  IF (MOD(V_CNT, 1000)=0) THEN
    COMMIT;
  END IF;

END LOOP;

如何为上面的块生成执行计划?

我问了类似的问题earlier并决定从我的存储过程中提取块并为单独生成执行计划。虽然我知道如何为简单查询生成计划,但我不知道如何为上面的循环块生成它们。

3 个答案:

答案 0 :(得分:3)

您的PL / SQL块可以在SQL中重写:

INSERT INTO table2 (firstname, lastname)
   SELECT fname, lastname
     FROM table2
    WHERE some_id IN (SELECT some_id FROM table1);

然后你可以“解释计划”上面的INSERT。

如果你必须进行批量提交,那么使用BULK COLLECT ... LIMIT和FORALL比循环游标更有效,特别是如果你正在处理数百万行。有用的链接:

答案 1 :(得分:1)

您无法为PL/SQL块生成执行计划,仅用于查询。

执行计划显示了声明式命令(SQL)如何在引擎盖下执行,i。即使用什么程序。它将声明性构造(集合操作)转换为过程(嵌套循环,散列连接,排序等)。

PL/SQL,顾名思义,是一种过程语言,定义了执行计划本身 - 在你的案例中嵌套循环。

如果您想查看内部查询的执行计划,则应复制它并发出EXPLAIN PLAN FOR …

请注意,这可以更有效地重写为:

BEGIN 
        FOR L IN
        (
        SELECT  MIN(some_id) AS minid, MAX(some_id) AS maxid
        FROM    (
                SELECT  some_id, rownum AS rn
                FROM    (
                        SELECT  some_id
                        FROM    table1
                        ORDER BY
                                some_id
                        )
                )
        GROUP BY
                TRUNC(rn / 1000)
        )
        LOOP
                INSERT
                INTO    TABLE2 (FIRSTNAME, LASTNAME)
                SELECT  FNAME, LASTNAME
                FROM    table1
                JOIN    table2
                ON      table2.some_id = table1.some_id
                WHERE   table1.some_id BETWEEN l.minid AND l.maxid
                V_CNT := V_CNT + 1;
                IF (MOD(V_CNT, 1000)=0) THEN
                        COMMIT;
                END IF;
        END LOOP;
END;

答案 2 :(得分:1)

如果您对程序PL / SQL代码的性能感兴趣,可能需要调查PL / SQL分析。

Profiler允许您收集有关PL / SQL的运行时性能的信息。分析运行完成后,您可以报告结果并查看每行执行次数的信息,每行的平均执行时间。这可以帮助您识别瓶颈,并指出您可能需要调整注意力的第一件事。

您最大的潜在回报是查看性能最差的代码并使其运行得更好。一旦改进,再次进行配置以验证您的改进并找到可能需要注意的下一个声明。

这里有一个很好的第一个介绍:Oracle's DBMS Profiler