代码之家  ›  专栏  ›  技术社区  ›  David Aldridge

SQL中TRUNCATE和DELETE的区别是什么

  •  217
  • David Aldridge  · 技术社区  · 16 年前

    两者之间有什么区别 TRUNCATE DELETE 在SQL中?

    31 回复  |  直到 6 年前
        1
  •  291
  •   David Aldridge    6 年前

    这里列出了一些不同之处。我强调了Oracle特有的功能,希望社区也能加入其他供应商特有的差异。大多数供应商常见的差异可以直接放在标题下方,下面突出显示差异。


    如果您想快速删除表中的所有行,并且确实确定要这样做,并且表中没有外键,那么截断可能比删除要快。


    语句类型

    Delete是DML,Truncate是DDL( What is DDL and DML?


    提交并回滚

    供应商变量

    Truncate可以回滚。

    PostgreSQL

    神谕

    因为TRUNCATE是DDL,所以它涉及两个提交,一个在语句执行之前,一个在语句执行之后。因此,Truncate无法回滚,并且Truncate进程中的失败将发出提交。

    但是,请参见下面的倒叙。


    空间复垦

    删除不恢复空间,截断恢复空间

    神谕


    行范围

    删除可用于删除所有行或仅删除行的子集。截断删除所有行。

    神谕


    对象类型

    Delete可以应用于表和集群内的表。Truncate仅适用于表或整个集群。(可能是特定于Oracle的)


    神谕

    删除不会影响数据对象id,但truncate会指定新的数据对象id 自创建表以来,从未对表进行过插入,即使是回滚的单个插入也会导致在截断时分配新的数据对象id。


    闪回可以跨删除工作,但截断可以防止闪回到操作之前的状态。

    但是,从11gR2开始,FLASHBACK归档功能允许这样做,Express Edition除外

    Use of FLASHBACK in Oracle http://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_flashback.htm#ADFNS638


    特权

    变量

    神谕


    重做/撤消


    索引

    神谕

    截断操作使不可用的索引再次可用。删除不会删除。


    外键

    当启用的外键引用表时,无法应用截断。使用delete进行处理取决于外键的配置。


    表锁定

    Truncate需要独占表锁,delete需要共享表锁。因此,禁用表锁是防止对表执行截断操作的一种方法。


    触发

    DML触发器不会在截断时触发。

    DDL触发器可用。


    远程执行

    不能通过数据库链接发出Truncate。


    标识列

    Truncate重置标识列类型的序列,delete不重置。


    结果集

    DELETE 语句可以将已删除的行返回给客户端。

    e、 g.在Oracle PL/SQL子程序中,您可以:

    DELETE FROM employees_temp
    WHERE       employee_id = 299 
    RETURNING   first_name,
                last_name
    INTO        emp_first_name,
                emp_last_name;
    
        2
  •  212
  •   Naresh Ravlani    7 年前

    +----------------------------------------+----------------------------------------------+
    |                Truncate                |                    Delete                    |
    +----------------------------------------+----------------------------------------------+
    | We can't Rollback after performing     | We can Rollback after delete.                |
    | Truncate.                              |                                              |
    |                                        |                                              |
    | Example:                               | Example:                                     |
    | BEGIN TRAN                             | BEGIN TRAN                                   |
    | TRUNCATE TABLE tranTest                | DELETE FROM tranTest                         |
    | SELECT * FROM tranTest                 | SELECT * FROM tranTest                       |
    | ROLLBACK                               | ROLLBACK                                     |
    | SELECT * FROM tranTest                 | SELECT * FROM tranTest                       |
    +----------------------------------------+----------------------------------------------+
    | Truncate reset identity of table.      | Delete does not reset identity of table.     |
    +----------------------------------------+----------------------------------------------+
    | It locks the entire table.             | It locks the table row.                      |
    +----------------------------------------+----------------------------------------------+
    | Its DDL(Data Definition Language)      | Its DML(Data Manipulation Language)          |
    | command.                               | command.                                     |
    +----------------------------------------+----------------------------------------------+
    | We can't use WHERE clause with it.     | We can use WHERE to filter data to delete.   |
    +----------------------------------------+----------------------------------------------+
    | Trigger is not fired while truncate.   | Trigger is fired.                            |
    +----------------------------------------+----------------------------------------------+
    | Syntax :                               | Syntax :                                     |
    | 1) TRUNCATE TABLE table_name           | 1) DELETE FROM table_name                    |
    |                                        | 2) DELETE FROM table_name WHERE              |
    |                                        |    example_column_id IN (1,2,3)              |
    +----------------------------------------+----------------------------------------------+
    
        3
  •  65
  •   Community CDub    4 年前

    截断

    删去

    DELETE命令用于从表中删除行。WHERE子句只能用于删除某些行。如果未指定WHERE条件,则将删除所有行。执行删除操作后,您需要提交或回滚事务以使更改永久化或撤消更改。请注意,此操作将触发表上的所有DELETE触发器。删除时将添加行级锁。

    http://www.orafaq.com/faq/difference_between_truncate_delete_and_drop_commands

        4
  •  24
  •   David Ferenczy Rogožan Hugo L.M    9 年前

    所有好答案,我必须补充:

    自从 TRUNCATE TABLE 这是一个DDL( Data Defination Language ),而不是DML( Data Manipulation Langauge )指挥部 Delete Triggers 不要跑。

        5
  •  22
  •   Shamseer K    6 年前
        6
  •  20
  •   David Ferenczy Rogožan Hugo L.M    9 年前

    对于SQL Server或MySQL,如果有自动递增的PK,truncate将重置计数器。

        7
  •  18
  •   Purvi Barot    5 年前

    TRUNCATE SQL查询删除表中的所有行,而不记录单个行的删除。

    • TRUNCATE是一个DDL命令。
    • TRUNCATE是使用表锁执行的,整个表被锁定 删除所有记录。
    • 我们不能将WHERE子句与TRUNCATE一起使用。
    • TRUNCATE删除表中的所有行。
    • 事务日志中的日志记录最少,因此在性能方面更快。
    • 存储表数据并仅记录中的页释放 事务日志。
    • 要在表上使用Truncate,至少需要对 桌子
    • Truncate使用的事务空间比Delete语句少。
    • 截断比删除快。

    删去

    • DELETE是一个DML命令。
    • DELETE使用行锁执行,表中的每一行都被锁定 删除。
    • 我们可以使用带有DELETE的where子句来过滤&删除特定的 记录。
    • DELETE命令用于根据位置从表中删除行 条件
    • DELETE语句一次删除一行并记录一个条目
    • 列keep DELETE的标识保留该标识。
    • 要使用Delete,您需要对表具有Delete权限。
    • “删除”可用于索引视图。
        8
  •  12
  •   Walter Mitty    16 年前

    Truncate不会在事务上下文中执行。

    然而,我看到truncate无意中破坏了引用完整性,并违反了其他约束。在事务之外修改数据所获得的力量必须与在没有网络的情况下走钢丝时所继承的责任相平衡。

        9
  •  10
  •   David Ferenczy Rogožan Hugo L.M    9 年前

    TRUNCATE DDL语句是否为 DELETE 是一个DML语句。以下是两者之间的区别:

    1. 截断 这是一个DDL( Data definition language )语句不需要提交即可使更改永久化。这就是truncate删除的行无法回滚的原因。另一方面 这是一个DML( Data manipulation language

    2. 截断 始终删除表中的所有行,使表为空且表结构保持不变 如果使用where子句,则可以有条件地删除。

    3. TRUNCATE TABLE 截断 陈述

    4. 截断 语句不会触发触发器,这与on delete触发器on相反 删去

    Here 是与主题相关的非常好的链接。

        10
  •  8
  •   DCookie    16 年前

    是的,删除速度较慢,截断速度较快。为什么?

        11
  •  6
  •   wpzone4u    10 年前

    如果您意外地使用Delete/Truncate从表中删除了所有数据。您可以回滚已提交的事务。恢复上次备份并运行事务日志,直到即将发生删除/截断。

    以下相关信息来自 a blog post :

    Sql中Delete和Truncate之间的区别。

    删除:

    • Delete语句使用行锁执行,表中的每一行都被锁定以进行删除。
    • 我们可以在where子句中指定过滤器。
    • 删除触发器中的活动,因为操作是单独记录的。
    • 比截断慢,因为它保留日志

    截断

    • Truncate是一个DDL命令。
    • Truncate table始终锁定表和页,但不锁定每一行,因为它会删除所有数据。
    • 无法使用Where条件。
    • Truncate table无法激活触发器,因为该操作不会记录单个行的删除。
    • 性能方面更快,因为它不保留任何日志。

    交易如果交易完成,意味着承诺,那么我们不能 rollback Truncate命令,但我们仍然可以回滚Delete命令 从日志文件中删除,如有必要,将其写入日志文件中

    如果您有一个外键约束,它引用了您要访问的表 尝试截断时,即使引用表没有 里面有数据。这是因为外键检查是用DDL完成的 而不是DML。这可以通过临时禁用 表的外键约束。

    已登录事务日志,这会使其变慢。截断表 也会删除表中的所有行,但不会记录 相反,每一行都记录 表,这使它更快。

    ~如果您使用从表中意外删除了所有数据 删除/截断。您可以回滚已提交的事务。恢复 上次备份并运行事务日志,直到删除/截断 就要发生了。

        12
  •  5
  •   Mangal Pardeshi    9 年前

    以下是我对这个问题的详细回答 the difference between DELETE and TRUNCATE in SQL Server

    删除数据 :首先,两者都可用于从表中删除行。

    :使用DELETE,您还可以使用另一个from子句根据另一个表中的行删除一个表中的行/view/rowset\U function\U limited。在FROM子句中,您还可以编写正常连接条件。实际上,您可以通过将SELECT替换为DELETE并删除列名,从不包含任何聚合函数的SELECT语句创建DELETE语句。
    用TRUNCATE你不能这样做。

    哪里 :截断不能具有WHERE条件,但删除可以。这意味着使用TRUNCATE无法删除特定行或特定行组。

    • 表演 :TRUNCATE TABLE更快,使用更少的系统和事务日志资源。

    • 事务日志 :DELETE语句一次删除一行,并在事务日志中为每行创建单独的条目。
    TRUNCATE TABLE通过取消分配用于存储表数据的数据页来删除数据,并在事务日志中仅记录页面取消分配。

    :执行DELETE语句后,表仍然可以包含空页。

    标识列 删除不会重置标识计数器。因此,如果要保留标识计数器,请改用DELETE。

    :DELETE可用于事务复制或合并复制中使用的表。
    而TRUNCATE不能用于事务复制或合并复制中涉及的表。

    • 回降

    限制 :如果外键引用了另一个表中的数据约束,则尝试删除该约束可能会失败。如果DELETE删除了多行,并且删除的行中的任何一行违反了触发器或约束,则该语句将被取消,返回错误,并且不会删除任何行。
    如果对视图使用DELETE,则该视图必须是可更新的视图。 不能对索引视图中使用的表使用TRUNCATE。

        13
  •  4
  •   Xander Xander    16 年前

    在SQLServer2005中,我相信您 回滚截断

        14
  •  4
  •   Community CDub    4 年前

    删去

    DELETE命令用于从表中删除行。WHERE子句只能用于删除某些行。如果未指定WHERE条件,则将删除所有行。执行删除操作后,您需要提交或回滚事务以使更改永久化或撤消更改。请注意,此操作将触发表上的所有DELETE触发器。

    截断

    TRUNCATE删除表中的所有行。无法回滚该操作,并且不会触发任何触发器。因此,TRUCATE速度更快,并且不像删除操作那样占用那么多的撤消空间。

    DROP命令从数据库中删除一个表。所有表的行、索引和权限也将被删除。不会触发DML触发器。无法回滚该操作。


    DROP和TRUNCATE是DDL命令,而DELETE是DML命令。因此,删除操作可以回滚(撤消),而删除和截断操作不能回滚。

    http://www.orafaq.com/faq/difference_between_truncate_delete_and_drop_commands

        15
  •  3
  •   SQLnbe    10 年前

    如果包装在事务中,则可以回滚TRUNCATE。

    http://blog.sqlauthority.com/2007/12/26/sql-server-truncate-cant-be-rolled-back-using-log-files-after-transaction-session-is-closed/

    http://sqlblog.com/blogs/kalen_delaney/archive/2010/10/12/tsql-tuesday-11-rolling-back-truncate-table.aspx

    TRUNCATE与DELETE是SQL访谈中臭名昭著的问题之一。只要确保你能向面试官解释清楚,否则你可能会失去这份工作。问题是没有多少人知道,所以如果你告诉他们答案是可以截断的话,他们很可能会认为答案是错误的。

        16
  •  3
  •   westyside    10 年前

    这两个操作的另一个区别是,如果表包含标识列,则该列的计数器在TRUNCATE下重置为1(或为该列定义的种子值)。删除不具有此影响。

        17
  •  2
  •   CaptainPicard    16 年前

    SQL> delete from t1;
    
    10918 rows deleted.
    
    Elapsed: 00:00:00.58
    
    Execution Plan
    ----------------------------------------------------------
       0      DELETE STATEMENT Optimizer=FIRST_ROWS (Cost=43 Card=1)
       1    0   DELETE OF 'T1'
       2    1     TABLE ACCESS (FULL) OF 'T1' (TABLE) (Cost=43 Card=1)
    
    
    
    
    Statistics
    ----------------------------------------------------------
             30  recursive calls
          12118  db block gets
            213  consistent gets
            142  physical reads
        3975328  redo size
            441  bytes sent via SQL*Net to client
            537  bytes received via SQL*Net from client
              4  SQL*Net roundtrips to/from client
              2  sorts (memory)
              0  sorts (disk)
          10918  rows processed
    
        18
  •  2
  •   Luc M    11 年前

    删去

    DELETE is a DML command
    DELETE you can rollback
    Delete = Only Delete- so it can be rolled back
    In DELETE you can write conditions using WHERE clause
    Syntax – Delete from [Table] where [Condition]
    

    截断

    TRUNCATE is a DDL command
    You can't rollback in TRUNCATE, TRUNCATE removes the record permanently
    Truncate = Delete+Commit -so we can't roll back
    You can't use conditions(WHERE clause) in TRUNCATE
    Syntax – Truncate table [Table]
    

    http://www.zilckh.com/what-is-the-difference-between-truncate-and-delete/

        19
  •  1
  •   Learning    16 年前

    最大的区别是truncate是非日志操作,而delete是。

    更多细节 here

        20
  •  1
  •   Bhushan Patil    11 年前

    DELETE语句:此命令根据where子句中给定的条件仅删除表中的行,如果未指定条件,则删除表中的所有行。但它不会释放包含表的空间。

    从表_中删除名称[其中条件];

    TRUNCATE语句:此命令用于删除表中的所有行,并释放包含表的空间。

        21
  •  0
  •   Oskar    16 年前

    简而言之,truncate不会记录任何内容(因此速度更快,但无法撤消),而delete会记录(并且可以是更大事务的一部分,将回滚等)。如果您在dev中的表中有不需要的数据,则通常最好将其截断,因为您不必冒填充事务日志的风险

        22
  •  0
  •   Jordan Ogren    16 年前

    它很方便的一个重要原因是,当您需要刷新数百万行表中的数据,但又不想重建它时。“Delete*”将花费很长时间,而Truncate的性能影响可以忽略不计。

        23
  •  0
  •   joel garry joel garry    16 年前

    无法通过数据库链接执行DDL。

        24
  •  0
  •   nathan    16 年前

    我想对matthieu的帖子发表评论,但我还没有这个代表。。。

        25
  •  0
  •   user2587360    11 年前

    这并不是说truncate不在SQL Server中记录任何内容。truncate不会记录任何信息,但会记录触发truncate的表的数据页解除分配。

    如果我们在开始时定义了事务,并且可以在回滚被截断的记录后恢复它,则可以回滚被截断的记录。但在提交截断事务后,无法从事务日志备份中恢复截断的记录。

        26
  •  0
  •   Robert Mars_win    10 年前

    Truncate也可以在这里回滚

    begin Tran
    delete from  Employee
    
    select * from Employee
    Rollback
    select * from Employee
    
        27
  •  0
  •   wpzone4u    10 年前

    参考检查 click here

        28
  •  0
  •   Gerald    10 年前

    通过发出TRUNCATE TABLE语句,可以指示SQL Server删除表中的每条记录,而不进行任何日志记录或事务处理。

        29
  •  0
  •   Ali    8 年前

    DELETE语句可以有一个WHERE子句来删除特定的记录,而TRUNCATE语句不需要任何记录,并且会擦除整个表。

        30
  •  0
  •   Mykhailo Seniutovych    8 年前

    microsoft sql server特有的另一个区别是 delete 你可以用 output

    delete from [SomeTable]
    output deleted.Id, deleted.Name
    

    你不能这样做 truncate