【问题标题】:Does TRUNCATE and DELETE produce same results?TRUNCATE 和 DELETE 是否产生相同的结果?
【发布时间】:2020-10-21 00:04:45
【问题描述】:

我知道听起来这个问题可能已经得到解答,但没有,我已经阅读了所有其他问题及其答案,而我的要求有所不同。 我知道 TRUNCATE 是 DDL 而 DELETE 是 DML,我知道 DELETE 可以与 WHERE 一起使用来删除一行,TRUNCATE 删除整个列,等等。

我已阅读所有这些答案: What's the difference between delete from table_a and truncate table table_a in MySQL? Difference between TRUNCATE and DELETE?

what is the difference between truncate and delete command in sql query

what is the diffrence between truncate and delete in sql server?

我要问的是这两个语句产生相同的结果吗?

DELETE FROM my_table;

TRUNCATE TABLE my_table;

我读得越多,我就越感到困惑,所以请说 TRUE 或 FALSE,然后请解释一下。

我知道这听起来可能很愚蠢,但帮助

【问题讨论】:

  • 我相信delete 会调用任何delete 触发器,而truncate 不会。
  • 这个答案适用于 Oracle 还是 MySQL?这是两种截然不同的动物。

标签: mysql sql oracle11g


【解决方案1】:

FALSE——我将在 MySQL 的 InnoDB 引擎的上下文中进行解释。您将问题标记为

删除

  • DELETE 可以是事务的一部分。动作可以回滚。它将旧记录复制到回滚段,如果您提交,那么这些记录版本将被垃圾收集。如果您回滚,则记录版本将恢复到表中。

  • DELETE 不会重置表的 AUTO_INCREMENT 计数器。

  • DELETE 不会创建新的表空间。表空间的大小不会缩小。所以它不会减少 table 在磁盘上的占用,它只会将 tablspace 中的大部分页面标记为“空闲”,即可能被后续数据覆盖。

  • DELETE 对受影响的每一行执行删除触发器。

  • DELETE 需要 DELETE 权限。

  • 您可以使用 JOIN 子句执行 DELETE,因此您可以选择在一个语句中从多个表中删除。

  • 如果您使用二进制日志记录更改并使用binlog_format=ROW,则二进制日志将填充与删除的行数一样多的行图像。这可能会占用大量空间。

截断表

  • 如您所说,TRUNCATE TABLE 是一个 DDL 语句,因此它执行 implicit commit

  • TRUNCATE TABLE 创建一个具有最小大小的新表空间,并删除原始表空间。

  • TRUNCATE TABLE 重置相应表的 AUTO_INCREMENT。

  • TRUNCATE TABLE 不会将任何记录复制到回滚段。

  • TRUNCATE TABLE 不执行任何触发器。

  • TRUNCATE TABLE 需要 DROP 权限。

  • 每个语句只能截断一个表。

  • TRUNCATE TABLE 不会在日志中为大表占用更多空间。 DDL 语句始终以语句格式写入二进制日志,即使您设置了binlog_format=ROW

  • TRUNCATE TABLE 基本上等价于这个序列:

      CREATE TABLE new_table LIKE original_table; -- i.e. with zero rows
      RENAME TABLE original_table TO table_to_drop, new_table TO original_table;
      DROP TABLE table_to_drop;
    

【讨论】:

    【解决方案2】:

    您询问了 Oracle 和 MySQL。此答案适用于 Oracle。

    没有。

    TRUNCATE 删除表的所有行并将堆的“高水位标记”重置为“零”,从而有效地从表空间中释放磁盘分配。

    DELETE 只是删除行,所以磁盘空间仍然会分配给表,即使它不再有任何行。

    【讨论】:

    • High Water 是指AutoIncrement Count
    • 在Oracle中,堆对应于存储表数据的磁盘块。每次插入一行时,该表的分配就会增加,这就是所谓的“高水位线”。即使您删除行,“高水位线”也会保留在那里。只有TRUNCATE 重置它。
    【解决方案3】:

    简单的答案,是的,它们在很大程度上产生了相同的结果——一个没有记录的表。虽然还有其他差异(例如如何处理触发器),但对我来说,最大的差异是:

    1. Truncate 不会更新日志,所以你不能回滚它
    2. 因为它不更新日志,所以运行得更快

    因此,我建议谨慎使用 TRUNCATE,但是,如果您完全确定您想要一个空表,我会使用它。

    【讨论】:

      【解决方案4】:

      删除

      这是一个 dml 命令。 它删除 Table 中特定的 Data 行。 我们可以在哪里条件。 可以提交。 可以回滚。 截断

      这是一个 ddl 命令。 它删除表中的数据。 我们可以在哪里条件。 不能回滚。自动提交。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-09
        • 2012-05-28
        • 2014-10-18
        相关资源
        最近更新 更多