2

当我尝试从包含两个 CLOB 字段的表中删除行时,我遇到了 Oracle 速度非常慢的问题。该表有数百万行,没有约束,删除是基于主键的。我重建了索引并重新计算了统计数据,但无济于事。

我可以做些什么来提高从此表中删除的性能?

4

5 回答 5

2

跟踪它,启用等待

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_monitor.htm#i1003679

在 UDUMP 目录中找到跟踪文件。TKPROF 吧。看看最后,它会告诉你数据库在那个 SQL 期间花时间做什么。以下链接很好地概述了如何分析性能问题。

http://www.method-r.com/downloads/doc_download/10-for-developers-making-friends-with-the-oracle-database-cary-millsap
于 2009-02-08T06:37:12.333 回答
1

在这种情况下,您的UNDO表空间似乎是瓶颈。

ROLLBACK检查删除数据后需要多长时间。如果它所花费的时间与查询本身的时间相当(在 内50%),那么肯定是这种情况。

当您执行DML查询时,您的数据(包括原始数据和更改数据)将写入重做日志,然后应用于数据文件和UNDO表空间。

删除数百万CLOB行需要将数百兆字节(如果不是千兆字节)复制到UNDO表空间,这本身需要数十秒。

你能做些什么呢?

  1. 创建更快UNDO:将其放在单独的磁盘上,使其不那么稀疏(创建更大的数据文件)。
  2. 使用ROLLBACK SEGMENTS而不是 managed ,在运行查询之前为这个查询和问题UNDO分配一个。ROLLBACK SEGMENTSET TRANSACTION USE ROLLBACK SEGMENT

如果不是这种情况,即ROLLBACK执行查询本身快得多,那么尝试使用您的REDO参数:

  1. 使用参数增加REDO缓冲区大小。LOG_BUFFER
  2. 增加日志文件的大小。
  3. 在单独的磁盘上创建日志文件,以便从第一个数据文件读取不会妨碍写入第二个数据文件,依此类推。

请注意,UNDO操作也会生成REDO,因此无论如何执行所有这些操作都是有用的。

NOLOGGING之前建议是无用的,因为它仅适用于此处列出的某些操作集,DELETE而不是这些操作之一。

于 2009-02-09T12:03:37.933 回答
1

使用 Oracle,您必须考虑删除行时生成的重做量。如果 CLOB 字段非常大,由于写入的重做量,Oracle 可能需要一段时间才能删除它们,并且您可能无能为力。

您可以执行的一项测试是查看删除是否需要很长时间在一行中,其中两个 CLOB 字段都设置为空。如果是这种情况,那么可能是索引更新需要很长时间。如果是这种情况,如果删除非常频繁,您可能需要调查合并索引(如果可能)。

如果表是派生表,意思是可以从其他表重建,可以看表的NOLOGGING选项。您可以使用最少的日志记录从源表重建表。

我希望这篇文章对一些人有所帮助,但是更多细节可以帮助诊断问题。

于 2009-02-08T01:13:57.850 回答
1

是否有任何引用该表的子表正在删除?(您可以在要从中删除的表上选择user_constraintswhere = primary key name)。r_constraint_name

如果 Oracle 需要查看另一个表以检查没有子记录,则删除可能会很慢。通常的做法是索引子表上的所有外键,所以这不是问题。

遵循 Gary 的建议,执行跟踪并将 TKPROF 结果发布在这里,有人将能够提供进一步的帮助。

于 2009-02-09T02:37:20.210 回答
0

删除的 CLOB 不会最终出现在 UNDOTBS 中,因为它们在 LOB 段中进行了版本化和保留。我认为它会在撤消中产生一些 LOBINDEX 更改。

如果您之前将 LOB 清空或清空,您是否真的用 DELETE 分开的提交来测量那个时间?如果您发出数千次删除,您是否使用批量提交?实例是否空闲?然后 AWR 报告应该告诉你发生了什么。

于 2009-10-07T02:11:36.250 回答