Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在Oracle 10g中使用CLOB字段从表中缓慢删除_Sql_Oracle_Plsql_Oracle10g_Clob - Fatal编程技术网

Sql 在Oracle 10g中使用CLOB字段从表中缓慢删除

Sql 在Oracle 10g中使用CLOB字段从表中缓慢删除,sql,oracle,plsql,oracle10g,clob,Sql,Oracle,Plsql,Oracle10g,Clob,当我试图从包含两个CLOB字段的表中删除行时,我遇到了一个Oracle非常慢的问题。该表有数百万行,没有约束,删除基于主键。我已经重建了索引并重新计算了统计数据,但没有结果 < >我能做些什么来提高这个表中删除的性能? 用Oracle,你必须考虑删除行时生成的重做量。如果CLOB字段非常大,Oracle可能需要一段时间才能删除它们,因为要写的重做操作太多了,而且您可能做不了多少 您可以执行的一个测试是查看删除是否在一行上花费很长时间,其中两个CLOB字段都设置为null。如果是这样,那么索引更新

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


< >我能做些什么来提高这个表中删除的性能?

用Oracle,你必须考虑删除行时生成的重做量。如果CLOB字段非常大,Oracle可能需要一段时间才能删除它们,因为要写的重做操作太多了,而且您可能做不了多少

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

如果该表是派生表,也就是说,它可以从其他表重建,您可以查看该表上的NOLOGGING选项。您可以使用最少的日志记录从源表重建表


我希望这篇文章能有所帮助,但是更多的细节可以帮助诊断这个问题

在启用等待的情况下跟踪它

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_monitor.htm#i1003679
在UDUMP目录中查找跟踪文件。特克洛夫。 看看结尾,它会告诉您数据库在SQL期间花了多少时间在做什么。下面的链接很好地概述了如何分析性能问题

http://www.method-r.com/downloads/doc_download/10-for-developers-making-friends-with-the-oracle-database-cary-millsap

是否有引用此表的子表正在从中删除?(您可以从
user\u constraints
中进行选择,其中
r\u constraint\u name
=要从中删除的表上的主键名称)

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


按照Gary的建议,执行跟踪并将TKPROF结果发布到这里,有人可以进一步提供帮助。

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

检查删除数据后执行
回滚所需的时间。如果它所花费的时间与查询本身的时间相当(在
50%
),那么肯定是这样

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

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

对此你能做些什么

  • 创建一个更快的
    UNDO
    :将其放在一个单独的磁盘上,使其不那么稀疏(创建一个更大的数据文件)
  • 使用
    回滚段
    而不是托管的
    撤消
    ,为此查询分配
    回滚段
    ,并在运行查询之前发出
    设置事务使用回滚段
  • 如果不是这样的话,我。e<代码>回滚
    执行速度比查询本身快得多,然后尝试使用您的
    重做
    参数:

  • 使用
    LOG\u buffer
    参数增加
    REDO
    缓冲区大小
  • 增加日志文件的大小
  • 在单独的磁盘上创建日志文件,以便从第一个数据文件读取数据不会妨碍向第二个数据文件写入数据,依此类推
  • 请注意,
    UNDO
    操作也会生成
    REDO
    ,因此不管怎样,这样做都很有用


    以前建议的
    NOLOGGING
    无效,因为它只应用于列出的某些操作集,
    DELETE
    不是这些操作之一。

    删除的CLOB不会在UNDOTBS中结束,因为它们在LOB段中进行版本控制和重新记录。我认为它将在撤销中生成一些LOBINDEX更改


    如果您以前为空或清空LOB,您是否实际使用commit和DELETE度量了该时间?如果发出数千次删除,是否使用批提交?实例是否空闲?然后AWR报告应该告诉您发生了什么。

    谢谢Nick。我运行的上一个测试将CLOB字段置空,删除速度仍然很慢。只有两个索引,单列上的PK索引和单列上的FK索引。这些索引与数据库大小方面的其他索引没有任何不同。有多少表对您的表具有外键约束?无论数字是多少,都要检查这些表、引用此表的id是否已编制索引。如果他们不是,这可能是你问题的根源。