我正在运行这样的查询:
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
答案 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问题。我认为如果我们做得更好所有人都在一个网站上一起工作。)
以下是一些想法:
select pdml_stats, pq_status, v$session.* from v$session;
select v$session.blocking_session, v$session.* from v$session;
来识别锁更容易。set autotrace on
运行。 db block gets
和redo size
第二次可能更大(第二个语句有一些额外的工作要做,虽然这可能不足以解释时差)。set autotrace on
运行,physical reads
可能会有很大差异。虽然拥有那么多数据,但是很大一部分数据被缓存的可能性很小。select * from v$sessmetric order by physical_reads desc,logical_reads desc, cpu desc;
或者查看v $ sysmetric_history。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如何执行这些语句以及是否存在任何差异等。
根据您正在做的事情,他们甚至可以帮助您更快地运行插入。例如,禁用索引,执行插入,然后重建它可以更快;或者可以暂时禁用日志记录。这显然取决于您的具体情况。