代码之家  ›  专栏  ›  技术社区  ›  Will

从空表中删除

  •  5
  • Will  · 技术社区  · 14 年前

    我有一个空表,以前有很多行。

    该表有大约10列,其中许多列上有索引,还有多个列上的索引。

    DELETE FROM item WHERE 1=1
    

    这大约需要40秒才能完成

    SELECT * FROM item
    

    这需要4秒钟。

    select*from项的执行计划如下:

    SQL> select * from midas_item;
    
    no rows selected
    
    Elapsed: 00:00:04.29
    
    Execution Plan
    ----------------------------------------------------------
     0      SELECT STATEMENT Optimizer=CHOOSE (Cost=19 Card=123 Bytes=73
          80)
    
    1    0   TABLE ACCESS (FULL) OF 'MIDAS_ITEM' (Cost=19 Card=123 Byte
          s=7380)
    
    
    
    
    
    Statistics
    ----------------------------------------------------------
          0  recursive calls
          0  db block gets
       5263  consistent gets
       5252  physical reads
          0  redo size
       1030  bytes sent via SQL*Net to client
        372  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed
    

    任何知道为什么要花这么长的时间,以及如何修复它的想法都将非常感谢!!

    5 回复  |  直到 14 年前
        1
  •  2
  •   Cornel Creanga    14 年前

    Select正在进行全表扫描。另一方面,删除(在Oracle中)必须将整个已删除的行存储在回滚段中,以便稍后撤消更改(因此,它甚至可能比插入还要慢)。

    你可以在Ask Tom论坛上找到一个与此相关的非常长且有用的讨论。根据您的业务案例,也许您可以应用更多的技术。

    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2345591157689

        2
  •  4
  •   Gary Myers    14 年前

    一种可能是锁。也就是说,表中有一行已被另一个删除操作提交并锁定。你的删除命令被锁定了。提交锁定事务后,您的删除就可以完成了。

    第二种可能是您首先运行了删除,这会将块从磁盘提取到缓存中(这需要时间)。当选择运行时,数据在缓存中,因此运行得更快。我认为这不太可能,因为您选择的统计数据表明“5252物理读取”,所以它没有从SGA缓存中获取它们。不过,可能涉及磁盘缓存。

    第三种可能性是有一个前后删除触发器(不是针对每一行)可以执行某些操作。

    第四种可能是删除导致块清除延迟。当实际删除这些行时,如果在提交之前将它们写入磁盘,那么它们仍然具有锁/事务信息。您的删除会出现,读取块,查看现在过时的事务信息,删除它并重新写入块。

    第五种可能性是争论。也许在删除的同时发生了更多的事情。

    很多可能性。如果可以复制它,那么使用wait事件进行跟踪,并通过tkprof运行它。

        3
  •  3
  •   user38123    14 年前

    如果您以前的表中充满了大量数据,那么Oracle会将其扫描到最高水位线,即使它现在没有数据。可以使用truncate语句重置hwm。

    Also on AskTom

        4
  •  2
  •   Tom H    14 年前

    如果表中有许多索引,则删除将需要一些时间,因为索引中的每个条目也需要删除。索引加快了读取过程,减慢了写入或其他修改过程(因此选择速度很快)。

    --编辑:抱歉,没有完全阅读问题。如果表为空,则它不能是索引问题。否则我会很惊讶的--

        5
  •  1
  •   Dark Castle    14 年前

    如果您经常从一个表中删除所有行,“truncate table xxx”通常比批量删除快得多。也许试试看你能跑多快。