sql truncate

This article gives you an insight into the SQL Truncate and SQL Delete commands behavior.

本文使您深入了解SQL截断和SQL删除命令的行为。

介绍 (Introduction)

In the article Difference between SQL Truncate and SQL Delete statements in SQL Server, we learned the difference between truncate and delete statements. You should go through this article before going further with this article.

在SQL Server中SQL Truncate和SQL Delete语句之间的区别一文中,我们了解了truncate和delete语句之间的区别。 在继续本文之前,您应该先阅读本文。

In this article, we will look at the following topics.

在本文中,我们将研究以下主题。

  • Can you Rollback a delete transaction and a truncate command? 您可以回滚删除事务和截断命令吗?
  • Which one is faster, Truncate or Delete and why? 截断或删除哪个更快,为什么?

回滚删除事务 (Rollback a delete transaction)

Let’s say you started two separate transactions – delete and truncate. Later, we want to roll back this transaction. We issued a rollback command for this.

假设您启动了两个单独的事务–删除和截断。 稍后,我们要回滚此事务。 为此,我们发出了回滚命令。

Now, a question for you – Does rollback command recovers data for both delete and truncate? You might think we cannot rollback a truncate statement. Let’s explore this practically.

现在,您遇到了一个问题– rollback命令是否同时恢复删除和截断的数据? 您可能会认为我们无法回滚截断语句。 让我们实践一下。

准备数据库环境 (Prepare a database environment)

Let’s create a new database [SQLShackDemo] for this article, along with a sample data table:

让我们为本文创建一个新的数据库[SQLShackDemo],以及一个示例数据表:

CREATE DATABASE SQLShackDemo;
GO
USE SQLShackDemo;
GO
CREATE TABLE test
(id     INT IDENTITY(1, 1), [Name] VARCHAR(10)
);
GO
INSERT INTO test([Name])
VALUES('SampleData');
GO 10

We have 10 records in the test table for demo purposes:

测试表中有10条记录用于演示:

We can use dynamic management view sys.dm_db_database_page_allocations(starting from SQL Server 2012) to list database pages belonging to the SQL table. This DMV takes the following arguments:

我们可以使用动态管理视图sys.dm_db_database_page_allocations(从SQL Server 2012开始)列出属于SQL表的数据库页面。 该DMV采用以下参数:

  • Database id: We can specify database id or use DB_ID() function to pass the current database id 数据库ID:我们可以指定数据库ID或使用DB_ID()函数传递当前数据库ID
  • Object id: This parameter takes object id we want to analyze. It is good to use OBJECT_ID(‘Object’) for automatically supplying this value 对象ID:此参数采用我们要分析的对象ID。 最好使用OBJECT_ID('Object')自动提供此值
  • The next two arguments are Index id and partition id. If we specify NULL values, it returns information about all indexes and partitions 接下来的两个参数是索引ID和分区ID。 如果我们指定NULL值,它将返回有关所有索引和分区的信息
  • In the last argument, we can specify LIMITED or DETAILED values. Let’s use DETAILED as it gives additional information compared to the LIMITED option output 在最后一个参数中,我们可以指定LIMITED或Detailed值。 让我们使用Detailed,因为它提供了与LIMITED选项输出相比的更多信息
SELECT allocated_page_file_id AS PageFID, allocated_page_page_id AS PagePID, allocated_page_iam_file_id AS IAMFID, allocated_page_iam_page_id AS IAMPID, object_id AS ObjectID, index_id AS IndexID, partition_id AS PartitionNumber, rowset_id AS PartitionID, allocation_unit_type_desc AS iam_chain_type, page_type AS PageType, page_level AS IndexLevel, next_page_file_id AS NextPageFID, next_page_page_id AS NextPagePID, previous_page_file_id AS PrevPageFID, previous_page_page_id AS PrevPagePID
FROM sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID('test'), NULL, NULL, 'DETAILED')
WHERE is_allocated = 1;
GO

Alternatively, we can use DBCC IND command as well and it returns almost the similar output:

另外,我们也可以使用DBCC IND命令,它返回几乎类似的输出:

DBCC IND('SQLShackDemo','test',1)

In the output, we can see two pages with PagePID 94 and 256:

在输出中,我们可以看到两个页面的页面PID为94和256:

  • PagePID 94: It is an IAM (Index Allocation Map) page. The IAM page has NULL values for IAMFID and IAMPID columns. PageType 10 denotes IAM page PagePID 94:这是一个IAM(索引分配图)页面。 IAM页的IAMFID和IAMPID列的值为NULL。 PageType 10表示IAM页面
  • PagePID 256: It is a data page. PageType 1 denotes a data page PagePID 256:这是一个数据页。 PageType 1表示数据页

Now, let’s begin a delete transaction using the begin transaction statement:

现在,让我们使用begin transaction语句开始删除事务:

USE SQLShackDemo;
GO
BEGIN TRANSACTION;
DELETE FROM [dbo].[test];

Since we did not specify the WHERE clause in the delete statement, it removes all ten rows from the test table:

由于我们未在delete语句中指定WHERE子句,因此它将删除测试表中的所有十行:

Do not commit the transaction as of now. We use the undocumented function fn_dblog to read transaction logs. You can refer to this article, How to continuously read Transaction log file data directly in a SQL Server database with fn_dblog and fn_dump_dblog to go through this command in detail.

到目前为止,请勿提交事务。 我们使用未记录的函数fn_dblog读取事务日志。 您可以参考本文, 如何使用fn_dblog和fn_dump_dblog直接直接在SQL Server数据库中连续读取事务日志文件数据,以详细了解此命令。

  • Note: You should be careful using this function in the production environment. Here, we are using it for demonstration purposes.

    注意:您应该在生产环境中小心使用此功能。 在这里,我们将其用于演示目的。

In the same query window with existing Begin SQL transaction, execute the following command of fn_dblog. This query filters the transaction logs for delete transaction ( defined as test1 in begin transaction statement):

在与现有Begin SQL事务相同的查询窗口中,执行以下fn_dblog命令。 此查询过滤用于删除事务的事务日志(在begin transaction语句中定义为test1):

USE SQLShackDemo;
GO
CHECKPOINT;
BEGIN TRANSACTION Test1;
DELETE FROM [dbo].[test];
SELECT [Current LSN], [transaction ID] tranID, [end time] endTime, AllocUnitId, Description, operation, Context
FROM ::fn_dbLog(NULL, NULL)
WHERE [Transaction ID] IN
(SELECT [Transaction ID]FROM fn_dbLog(NULL, NULL)WHERE [Transaction Name] = 'Test1'
);

SQL delete statement removes individual row and logs entry for each row in the transaction log. We removed 10 rows from the test table, and output also reflects LOB_DELETE_ROWS entry for an individual row. This LOP_DELETE_ROWS operation occurs for the delete statement. We can also see a total of 11 rows in the output of fn_dblog for this delete operation:

SQL delete语句删除单个行,并在事务日志中为每一行记录日志条目。 我们从测试表中删除了10行,并且输出还反映了单个行的LOB_DELETE_ROWS条目。 LOP_DELETE_ROWS操作发生在delete语句中。 我们还可以在fn_dblog的输出中看到此删除操作共有11行:

Execute the select statement in the same transaction, and it returns zero in the output:

在同一事务中执行select语句,并在输出中返回零:

Select count(*) from [dbo].[test];

Now, issue a rollback statement and check for the number of rows in the test table. It returns 10 rows in the output. It shows you can rollback a delete transaction:

现在,发出回滚语句并检查测试表中的行数。 它在输出中返回10行。 它显示您可以回滚删除事务:

Rollback transaction
Select count(*) from [dbo].[test];

回滚截断事务 (Rollback a truncate transaction)

Now, we want to check whether we can rollback a truncate statement or not. For this demo, drop the test table and recreate it with the same 10 rows from the script shared above.

现在,我们要检查是否可以回滚截断语句。 对于此演示,删除测试表并使用上面共享的脚本中的相同10行重新创建它。

Once we have an environment ready, start a new transaction and truncate table from the following script:

一旦我们准备好环境,就可以开始新事务并从以下脚本截断表:

USE SQLShackDemo;
GO
BEGIN TRANSACTION;
TRUNCATE TABLE [dbo].[test];

In the following query, we started a transaction T1 and filtered output of fn_dblog for that particular transaction:

在以下查询中,我们启动了事务T1并为该特定事务过滤了fn_dblog的输出:

USE SQLShackDemo;
GO
CHECKPOINT
Go
BEGIN TRANSACTION T1;
TRUNCATE TABLE [dbo].[test];
SELECT [Current LSN], [transaction ID] tranID, [end time] endTime, AllocUnitId, Description, operation, Context
FROM ::fn_dbLog(NULL, NULL)
WHERE [Transaction ID] IN
(SELECT [Transaction ID]FROM fn_dbLog(NULL, NULL)WHERE [Transaction Name] = 'T1'
);

For SQL truncate, we do not get an entry for individual rows in the transaction log. It deallocates the extent, as shown below:

对于SQL截断,我们不会在事务日志中获得单个行的条目。 它取消分配范围,如下所示:

Let’s issue rollback transaction command and check records in a test table. We get our records back. Yes, it proves that we can rollback a SQL Truncate statement as well:

让我们发出rollback transaction命令并检查测试表中的记录。 我们得到我们的记录。 是的,它证明我们也可以回滚一条SQL Truncate语句:

SQL Server minimizes logging for truncate. To prove this point, insert more records in the test table using the following query:

SQL Server最小化了截断的日志记录。 为了证明这一点,请使用以下查询在测试表中插入更多记录:

INSERT INTO test([Name])
VALUES('SampleData');
GO 90

We have 100 records in the test table. Now, check the transaction log records count for both truncate and delete operations using scripts specified above.

测试表中有100条记录。 现在,使用上面指定的脚本检查事务日志记录中的截断和删除操作计数。

  • Transaction log records for delete: 101

    用于删除的事务日志记录:101

  • Transaction log records for truncate: 12

    截断的事务日志记录:12

From the above screenshots, we can verify that as the record count increases in a table, transaction log record count also increases for delete statement. It does not change much for the truncate statement. Hence,we can see, it takes more time to delete records in comparison with truncate for a huge table. If we wish to remove all records from a table, we should use truncate because it is fast and minimize transaction log growth.

从上面的屏幕截图中,我们可以验证表中记录数的增加,对于delete语句,事务日志记录数的增加。 截断语句的变化不大。 因此,我们看到,与截断大型表相比,删除记录要花费更多的时间。 如果我们希望从表中删除所有记录,则应使用truncate,因为它速度快并且可以最大程度地减少事务日志的增长。

结论 (Conclusion )

In this article, we explored internals of the SQL Truncate and SQL Delete statement. It also shows the reason for a fasater execution of the truncate statement in comparison with the delete statement. You should use commands as per your requirements.

在本文中,我们探讨了SQL Truncate和SQL Delete语句的内部。 与delete语句相比,它还显示了执行fruner截断语句的原因。 您应该根据需要使用命令。

翻译自: https://www.sqlshack.com/the-internals-of-sql-truncate-and-sql-delete-statements/

sql truncate

sql truncate_SQL Truncate和SQL Delete语句的内部相关推荐

  1. SQL中truncate table和delete的区别

    truncate table table_namedelete from table_namedrop table table_name truncate table在功能上与不带where子句的de ...

  2. SQL中truncate table和delete的区别 --转

    内容: http://www.cnblogs.com/GT_Andy/archive/2010/01/28/1921871.html 感谢博主的分享!!! 转载于:https://www.cnblog ...

  3. 【ABAP】OPEN SQL(六)「DELETE语句 | MODIFY语句」

  4. sql truncate_如何在SQL Delete和SQL Truncate语句后使用数据库备份恢复数据

    sql truncate This article explores the recovery of data removed by SQL Delete and SQL Truncate state ...

  5. mysql语句delete报错_MySQL delete语句的问题

    以前遇到过几次这个问题,都觉得问题不大,所以没有记录,但是这次又遇到了,而且没有第一时间想起来,所以还是有记录下的必要 MySQL    delete语句使用子查询操作同一张表的时候会抛出 DELET ...

  6. SQL Server中drop、truncate和delete语句的用法

    SQL Server中drop.truncate和delete语句的用法 drop  删除表和表中的所有数据(不保留表的结构) drop table tablename truncate   删除表中 ...

  7. sql语句语法多表关联_SQL Delete语句-如何删除行或表,语法示例

    sql语句语法多表关联 To delete a record in a table you use the  DELETE  statement. 要删除表中的记录,请使用DELETE语句. Be c ...

  8. SQL的TRUNCATE和DELETE

    目录 Truncate和Delete之间的区别是什么? 何时使用TRUNCATE 何时使用DELETE命令 结论 在SQL Server中,有几种方法可以从表中删除行.您可以使用TRUNCATE和DE ...

  9. SQL更新(INSERT,UPDATE,DELETE)语句的一般格式及注意事项

    目录 写在文章前 关于更新语句 INSERT语句 UPDATE语句 DELETE语句 更新语句的通用注意事项 写在文章前 本文从SQL语句格式角度,谈一谈SQL更新语句的基本格式及其在Oracle中的 ...

最新文章

  1. 《SolidWorks 2016中文版机械设计从入门到精通》——第1章 认识SolidWorks1.1 SolidWorks概述...
  2. php拍照从手机相册中选择,Android获取图片:拍照和从相册中选择
  3. malloc 初始化_你真的了解 NSObject 对象的初始化吗?
  4. java填写xls模板_Java 新建excle文件并填充模版内容
  5. efcore 批量_EFcore使用EFCore.BulkExtensions 批量增加、删除、修改
  6. datagrip jdbc驱动_datagrip离线安装驱动jar
  7. 目前使用的工具及开发方式
  8. 函数式编程中的两个棘手问题
  9. 课时5 企业Web服务器现场抓鸡案例分享
  10. 发票识别OCR和发票扫描仪
  11. 箱形图的优缺点,python绘制箱形图
  12. php 问号乱码,如何解决php问号乱码的问题
  13. 使用WIFI模块与MQTT服务器进行透传数据通讯(M0E1系列)
  14. 调css p 段落间距,CSS段落第一个文字空两格缩进text-indent 和 文字之间间距调整letter-spacing...
  15. 计算机基础知识(基础入门小白专属)五
  16. Vert.x(vertx) Web开发-路由
  17. 关于MaxCompute的基本了解
  18. 数据结构题及c语言版严第七章答案,数据结构第七章习题答案.doc
  19. 【树莓派】DS18B20温度传感器
  20. Office2010,PPT,EXCEL如何插入日历控件

热门文章

  1. c++中sin,cos,arcsin等和在C/C++中使用pi (π) 值
  2. 关于css的一切(updating...)
  3. LeetCode(748)——最短完整词(JavaScript)
  4. LeetCode(700)——二叉搜索树中的搜索(JavaScript)
  5. pgp 私钥需要什么样的保护措施_网络货运作为物流行业的掌舵者企业申报需要满足的条件重点有哪些...
  6. 线程的五大状态及转换
  7. 为什么这几年餐饮创业突然火起来了?
  8. 姐弟恋的人最后都是什么结局?
  9. 你最缺钱的时候是怎么度过的?
  10. 注意力是非常宝贵的资源