截断大桌子

时间:2018-10-17 22:47:53

标签: sql-server tsql database-administration

我有一个包含7亿个数据的表,这是最快清空该表的最佳方法。我相信使用delete语句不适合此类操作,因为它将记录整个事务。

4 个答案:

答案 0 :(得分:2)

据我所知,三种方式

  1. 截断表
  2. 对表进行脚本编写,然后删除表并使用脚本重新创建表。
  3. 假设该表具有PK,然后创建一个相似的表,然后使用分区输入/输出将表切换到新表,然后删除新创建的表。

欢迎您为这个简单而有趣的问题提供更多思路。

答案 1 :(得分:0)

如标题所示-如果您正在寻找可能的最快方法,则应截断表格。

TRUNCATE TABLE [dbo].[mytable]

截断表格有the following advantages

  

与DELETE语句相比,TRUNCATE TABLE具有以下内容   优点:

     
      
  • 使用较少的事务日志空间。
  •   
     

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

     
      
  • 通常使用较少的锁。
  •   
     

使用行锁执行DELETE语句时,   该表被锁定以删除。 TRUNCATE TABLE始终锁定   表(包括架构(SCH-M)锁)和页面,但不是每一行。

     
      
  • 没有例外,表中剩余零页。
  •   
     

执行DELETE语句后,该表仍可以包含   空页。例如,堆中的空页面无法释放   没有至少一个排他(LCK_M_X)表锁。如果删除   操作不使用表锁,该表(堆)将包含   许多空白页。对于索引,删除操作可以留空   后面的页面,尽管这些页面会被   后台清理过程。

     

TRUNCATE TABLE删除表中的所有行,但表结构   并保留其列,约束,索引等。删除   表定义除了其数据外,还使用DROP TABLE   声明。

     

如果表包含一个标识列,则该列的计数器   重置为该列定义的种子值。如果没有种子   定义时,使用默认值1。要保留身份计数器,   改为使用DELETE。

截断还会重置身份,因此,如果需要保留身份,则应首先获取标识符(表中的脚本),然后在截断后将表设置回该标识符。另外,您也可以只编写表格脚本,将其删除然后重新创建。

或者,您可以使用以下命令轻松切换出表数据

--May need to script out table if you have things like compression.
select TOP 0 * into mytable_old from mytable; 

ALTER TABLE mytable SWITCH TO mytable_old;

DROP TABLE mytable_old;

切换数据是一个元数据更改,磁盘上实际上没有数据移动,因此这通常是一个相当快的操作(假设在表上没有阻塞),并且I / O很少。删除该表当然会像往常一样产生I / O惩罚。

最后-如果由于某种原因您在表上有大量的锁,则可能要慢慢从表中删除记录。这不是很快,但是当我使用它时,由于删除窗口很快,所以它将阻塞保持在最低限度。但是,这将向日志中写入更多信息,因此,如果您有类似复制的内容,这可能会使日志读取器代理陷入困境,因为它将有太多记录要处理(关于此问题的解决方法有整个主题,但是我我离开了轨道)。话虽这么说-这更多是一种特殊情况下的删除,可能仅应作为最后的手段使用(或者当您需要指定要删除的某些内容时)。

;WITH CTE AS
(
   select TOP 1000 *  -- Depending on the blocking, you may want to up/down this amount
   from mytable
)
delete from CTE;

WHILE (@@ROWCOUNT > 0)
BEGIN
   WAITFOR DELAY '00:00:03'; -- Gives times for other queries to process/helps with blocking

   ;WITH CTE AS
   (
     select TOP 1000 *
     from mytable
   )
   delete from CTE;
END

答案 2 :(得分:0)

如果要删除该表中的所有行,则最简单的选择是按以下方式截断表:

TRUNCATE TABLE TableName

参考:How to delete large data of table in SQL without log?

答案 3 :(得分:0)

bes方法是TRUNCATE TABLE

<|"January" -> 70.09, "February" -> 66.39, "March" -> 65.7829, "April" -> 70.189, "May" -> 69.5391, "June" -> 64.3086,   "July" ->
62.4019, "August" -> 63.3765, "September" -> 65.9926, "October" -> 70.4233|>