Oracle插入执行时间过长

时间:2011-06-13 12:43:21

标签: oracle insert locking

我对Oracle 10g XE执行插入的时间感到困惑。我从xml文件中实现了批量插入到具有程序化事务管理的几个表中。为什么一个插件会在瞬间执行,另一个插件会在10分钟以上执我等不及了,停下来。我认为还有一些比较复杂的东西我还没注意过。

更新

我使用Monitor找到了锁。

Waits     
Event   enq: TX - row lock contention
name|mode   1415053316
usnusnusnusn<<16 | slot 327711
sequence    162

SQL   
INSERT INTO ESKD$SERVICESET (ID, TOUR_ID, CURRENCY_ID) VALUES (9, 9, 1)

这是什么意思,我该如何解决?

4 个答案:

答案 0 :(得分:2)

TX- Enqueues众所周知,快速谷歌会给你一个明确的answer

从那篇文章:

  

1)当会话正在等待另一个会话已经持有的行级别锁定时,发生模式6中的TX等待。当一个用户正在更新或删除另一个会话希望更新或删除的行时,会发生这种情况。这种类型的TX enqueue wait对应于等待事件enq:TX - 行锁争用。

如果您有大量同时插入和更新表,您希望每个事务尽可能短。进入,离开...介于两者之间的时间越长,其他交易的延迟就越长。

PURE GUESS:

我觉得你提到的“程序化交易管理”是你试图使用像QUEUE这样的表。插入开始记录,频繁更新以更改状态,然后删除“已完成”记录。这总是很麻烦。

答案 1 :(得分:0)

如此少的具体信息很难回答这个问题。所有我能告诉你的是为什么会这样。

如果您正在进行INSERT ... SELECT ...批量插入,那么您的SELECT查询可能效果不佳。可能存在大量表连接,无效使用内联视图和其他可能会对INSERT的性能产生负面影响的资源。

尝试在解释计划中执行SELECT查询,以了解优化工具如何推导计划以及评估查询的成本。

你提到的另一件事是可能的锁定。这可能是这种情况,但您需要使用OEM工具进行分析,以确定无误。

要考虑的另一件事可能是您的表上没有索引,或者这些表的统计信息可能已过期。过时的统计信息会极大地影响大型表上查询的性能。

答案 2 :(得分:0)

请参阅sites.google.com/site/embtdbo/wait-event-documentation/oracle-enqueues

锁定等待表示冲突可能很容易导致性能问题。从表面上看,当该键值的第一次插入尚未提交时,问题可能是插入重复的键值。您看到“enq:TX - 行锁争用”的锁定是因为一个会话正在尝试修改另一个会话中的未提交数据。此特定锁定等待事件有4个常见原因:

  1. 更新/删除同一行
  2. 插入相同的uniq密钥
  3. 修改相同的位图索引块
  4. 删除/更新外键的父值

我们可以消除您正在进行插入的第一个和最后一个案例。 如果您没有涉及位图索引,您应该能够识别第二个。如果您涉及到位图索引并且涉及到uniq密钥,那么您可以轻松调查是否有活动会话历史记录(ASH)数据,但遗憾的是Oracle XE没有。另一方面,您可以使用S-ASH自行收集,请参阅:http://ashmasters.com/ash-simulation/。使用ASH或S-ASH,您可以运行类似

的查询

col event for a22
col block_type for a18
col objn for a18
col otype for a10
col fn for 99
col sid for 9999
col bsid for 9999
col lm for 99
col p3 for 99999
col blockn for 99999
select
       to_char(sample_time,'HH:MI') st,
       substr(event,0,20) event,
       ash.session_id sid,
       mod(ash.p1,16)  lm,
       ash.p2,
       ash.p3, 
       nvl(o.object_name,ash.current_obj#) objn,
       substr(o.object_type,0,10) otype,
       CURRENT_FILE# fn,
       CURRENT_BLOCK# blockn, 
       ash.SQL_ID,
       BLOCKING_SESSION bsid
       --,ash.xid
from v$active_session_history ash,
      all_objects o
where event like 'enq: TX %'
   and o.object_id (+)= ash.CURRENT_OBJ#
Order by sample_time
/
哪个输出会像:
ST    EVENT                  SID  LM     P2   P3 OBJ   OTYPE  FN BLOCKN SQL_ID         BSID
10:41 enq: TX - row lock c   143   4 966081 4598 I1    INDEX   0      0 azav296xxqcjx   144
10:41 enq: TX - row lock c   143   4 966081 4598 I1    INDEX   0      0 azav296xxqcjx   144
10:41 enq: TX - row lock c   143   4 966081 4598 I1    INDEX   0      0 azav296xxqcjx   144
10:41 enq: TX - row lock c   143   4 966081 4598 I1    INDEX   0      0 azav296xxqcjx   144
显示对象名称“OBJ”和具有争用的对象类型“OTYPE”,并且该类型是INDEX。从那里你可以查找INDEX的类型来验证它是位图。 如果问题是位图索引,那么您应该使用位图索引重新评估或重新访问数据加载和/或修改的方式以减少冲突。

如果问题不是BITMAP索引,那么它正在尝试插入重复键。其他一些进程已插入相同的键值但尚未提交。然后,您的进程尝试插入相同的键值,并且必须等待第一个会话提交或回滚。

有关更多信息,请参阅此链接:lock waits

答案 3 :(得分:0)

这意味着,您的序列缓存很小。增加它。