SQL Plus 与 Toad IDE - 在 SQL Plus 中运行插入需要更长的时间
Posted
技术标签:
【中文标题】SQL Plus 与 Toad IDE - 在 SQL Plus 中运行插入需要更长的时间【英文标题】:SQL Plus vs Toad IDE - Running insert in SQL Plus takes significantly longer 【发布时间】:2011-05-20 19:40:34 【问题描述】:我正在运行这样的查询:
INSERT INTO TableA (colA, colB)
Select ColA, ColB
from TableB
这是一个巨大的插入,因为它查询超过 200 万行,然后将它们插入到表中。我的问题是关于性能的。当我在 toad 中运行查询时,查询大约需要 4-5 分钟才能运行。
当我通过 sqlplus 运行查询时,它需要更长的时间。它已经运行了 40 分钟以上,但还没有完成。我什至通过关闭服务器输出进行了一些小的调整,以防影响性能。
关于通过 sqlplus 运行查询,我应该注意哪些调整?有什么方法可以找出不同客户端执行/处理查询的方式的差异?
注意:这是我将数据从表 A 传输到表 B 的唯一方法。我研究了 imp/exp 和 impdp/expdp,但在我的情况下这是不可能的。
蟾蜍 - v. 9.6.1.1 SqlPlus - 9.2.0.1.0 甲骨文数据库 - 10g
【问题讨论】:
没有 dba.***.com 吗?这不是真正的编程相关,这是一个工具的东西,可能吗?具体来说,您可能需要查看 toad 在它创建的连接上设置了哪些选项。 sqlplus 可能没有为您做 任何事情,而 toad 可能是。虽然我不知道为什么它会对客户端本身没有做任何事情的查询产生任何影响...... 【参考方案1】:这听起来像是涉及到其他事情。我的疯狂猜测是您的 SQL*Plus 会话被阻止了。你能检查一下 v$lock 看看是不是这样吗?有很多脚本/工具可以检查您的会话当前花费的时间。弄清楚这一点,然后从那里开始。我个人喜欢 Tanel Poder 的 Snapper 脚本 (http://tech.e2sn.com/oracle-scripts-and-tools/session-snapper)。
【讨论】:
【参考方案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 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。
您可能需要考虑并行和附加提示。您可能可以使该查询的运行速度提高 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。)
【讨论】:
【参考方案3】:非常明显的一点,但众所周知,它会绊倒人们……tableA
上有没有索引;如果是的话,它们中的任何一个都是独一无二的;如果是,在 SQL*Plus 中再次运行之前,您是否提交或回滚了 Toad 会话?正如@Craig 所建议的那样,不这样做是获得障碍的一种简单方法。在这种情况下,它永远不会完成 - 您的 40 多分钟等待是在第一行插入时阻塞。
如果有任何索引,最好在插入时删除它们,然后再重新创建它们,因为这通常会快得多。
【讨论】:
【参考方案4】:正如其他人已经建议的那样,有很多事情可能会导致选择/插入大量数据的语句表现不佳(并且不一致)。虽然我看到 Toad 有时会做一些事情来提高性能,但我从未见过它做任何事情如此快得多,所以我倾向于认为它更多地与数据库而不是工具有关。
我会要求 DBA 在慢语句运行时检查您的会话和数据库。他们应该能够给你一些正在发生的事情的迹象——他们将能够检查任何问题,例如锁定或过度的日志文件切换。他们还将能够跟踪两个会话(Toad 和 SQL Plus),以查看 Oracle 如何执行这些语句以及是否存在任何差异等。
根据您正在做什么,他们甚至可以帮助您更快地运行插入。例如,禁用索引,插入,然后重建它会更快;或者可能暂时禁用日志记录。这显然取决于您的具体情况。
【讨论】:
抱歉,刚刚发现这是一个老问题。无论如何我都会在这里留下答案 - 我仍然认为它的要点(“与 DBA 交谈”)对于遇到此问题的其他人来说是一个有用的建议以上是关于SQL Plus 与 Toad IDE - 在 SQL Plus 中运行插入需要更长的时间的主要内容,如果未能解决你的问题,请参考以下文章
如何将 SQL 开发人员/Toad 连接到 Oracle 8i