SQL Plus与Toad IDE - 在SQL Plus中运行插入需要更长的时间

时间:2011-05-20 19:40:35

标签: sql performance oracle sqlplus toad

我正在运行这样的查询:

INSERT INTO TableA (colA, colB)
Select ColA, ColB 
from TableB

这是一个巨大的插入,因为它查询超过200万行,然后将它们插入表中。我的问题是关于表现。当我在toad中运行查询时,查询大约需要4-5分钟才能运行。

当我通过sqlplus运行查询时,它会占用更长的时间。它已经运行了40分钟+并且还没有完成。我甚至通过设置服务器输出来进行一些微调,以防影响性能。

关于通过sqlplus运行查询,我应该注意哪些调整?有没有办法找出不同客户端执行/处理查询的方式有何不同?

注意:这是我可以将数据从表A传输到表B的唯一方法。我查看了imp / exp和impdp / expdp,但在我的情况下这是不可能的。

Toad - v.9.6.1.1 SqlPlus - 9.2.0.1.0 Oracle DB - 10g

4 个答案:

答案 0 :(得分:5)

这听起来有其他相关内容。我的猜测是你的SQL * Plus会话被阻止了。你能检查一下v $ lock,看看是不是这样吗?有很多脚本/工具需要检查,以查看您的会话当前花费的时间。想出来,然后从那里走。我个人喜欢Tanel Poder的Snapper脚本(http://tech.e2sn.com/oracle-scripts-and-tools/session-snapper)。

答案 1 :(得分:2)

这可能是一千件事。 (@John Gardner:这就是为什么我不是dba.stackexchange.com的忠实粉丝的一个原因 - 在你知道答案之前,你不会知道这是编程问题还是DBA问题。我认为如果我们做得更好所有人都在一个网站上一起工作。)

以下是一些想法:

  • 不同的会话设置 - 可以启用,强制或禁用并行dml和并行查询。查看您的登录脚本,或使用select pdml_stats, pq_status, v$session.* from v$session;
  • 查看会话信息
  • 锁定,正如@Craig建议的那样。虽然我认为查看select v$session.blocking_session, v$session.* from v$session;来识别锁更容易。
  • 延迟块清除会使第二个查询变慢。使用set autotrace on运行。 db block getsredo size第二次可能更大(第二个语句有一些额外的工作要做,虽然这可能不足以解释时差)。
  • 缓冲区缓存可以使第二个查询更快。使用set autotrace on运行,physical reads可能会有很大差异。虽然拥有那么多数据,但是很大一部分数据被缓存的可能性很小。
  • 其他会话可能会占用大量资源。查看select * from v$sessmetric order by physical_reads desc,logical_reads desc, cpu desc;或者查看v $ sysmetric_history。
  • 您可能需要考虑并行和追加提示。您可以使查询运行速度提高10倍(尽管该方法存在一些缺点,例如 数据最初是不可恢复的。)
  • 此外,为了进行测试,您可能需要使用更小的尺寸。使用and rownum <= 10000之类的内容运行插入。性能调整非常困难,如果你可以运行它会有很大帮助 陈述经常。总有一些吸虫,你想忽略异常值,但只有两个样本你不能这样做。
  • 您可以查看每次运行的一些详细统计信息,但您可能需要使用INSERT /*+ GATHER_PLAN_STATISTICS */...运行查询。然后运行它来查找sql​​_id:select * from v$sql where sql_text like '%INSERT%GATHER_PLAN_STATISTICS%'; 然后运行此操作以查看每个步骤的详细信息:select * from v$sql_plan_statistics_all where sql_id = '<sql_id from above>'; (在11g中,你可以使用v $ sql_monitor,甚至更好的dbms_sqltune.report_sql_monitor。)

答案 2 :(得分:0)

一个非常明显的观点,但众所周知,绊倒人们...... tableA上是否有任何索引;若其中任何一个都是独一无二的;如果是这样,你在SQL * Plus中再次运行之前提交或回滚Toad会话?正如@Craig建议的那样,不这样做是一种简单的方法。在这种情况下它永远不会完成 - 你的40多分钟等待是在第一行插入时阻塞。

如果有任何索引,你可能会更好地放弃它们,同时你进行插入并在之后重新创建它们,因为它通常要快得多。

答案 3 :(得分:0)

正如其他人已经建议的那样,有很多事情可能会导致选择/插入那么多数据的语句执行得很糟糕(并且不一致)。虽然我看到Toad有时会做一些提高性能的事情,但我从来没有见过它做得更快所以更快,所以我倾向于认为它更多的事情要做使用数据库而不是工具。

我会要求DBA在慢速语句运行时检查您的会话和数据库。他们应该能够给你一些关于发生了什么的指示 - 他们能够检查任何问题,例如锁定或过多的日志文件切换。他们还可以跟踪两个会话(Toad和SQL Plus),以了解Oracle如何执行这些语句以及是否存在任何差异等。

根据您正在做的事情,他们甚至可以帮助您更快地运行插入。例如,禁用索引,执行插入,然后重建它可以更快;或者可以暂时禁用日志记录。这显然取决于您的具体情况。