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;
USE SQLShackDemo;
CREATE TABLE test
(id INT IDENTITY(1, 1),
[Name] VARCHAR(10)
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采用以下参数:
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;
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;
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;
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;
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;
CHECKPOINT
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
用法有两种:TRUNC(NUMBER)表示截断数字,TRUNC(date)表示截断日期。
(1)截断数字:
格式:TRUNC(n1,n2),n1表示被截断的数字,n2表示要截断到那一位。n2可以是负数,表示截断小数点前。注意,TRUNC截断不是四舍五入。
SQL> select TRUNC(15.79) from dual;
TRUNC(15.79) ------------ 15
SQL> select TRUNC(15.79,1) from du
(三)truncate和delete的区别
1. truncate 和 delete 都可以清除表的所用数据,但 truncate 比 delete 的速度快,且使用的系统和
事务日志资源少。
转自:http://www.studyofnet.com/news/555.html
本文导读:删除表中的数据的方法有delete,truncate, 其中TRUNCATE TABLE用于删除表中的所有行,而不记录单个行删除操作。TRUNCATE TABLE 与没有 WHERE 子句的 DELETE 语句类似;但是,TRUNCATE TABLE 速度更快,使用的系统资源和事务日志资源更少。下面介...
文章目录第150章 SQL函数 TRUNCATE大纲参数描述TRUNCATE, ROUND, and $JUSTIFY示例
第150章 SQL函数 TRUNCATE
标量数值函数,按指定位数截断一个数。
{fn TRUNCATE(numeric-expr,scale)}
numeric-expr - 要截断的数字。数字或数字表达式。
scale - 计算结果为一个整数的表达式,该整数指定要截断的位数,从小数点开始计算。可以是零、正整数或负整数。如果比例是小数,会将其舍入为最接近的整数。
SQL函数是每个SQL数据库使用者都必须要掌握的,下面就将为您介绍SQL中TRUNC函数的两种用法,供您参考,希望对您学习SQL函数的使用能有帮助。1.TRUNC(for dates)TRUNC函数为指定元素而截去的日期值。其具体的语法格式如下:TRUNC(date[,fmt])其中:date 一个日期值fmt 日期格式,该日期将由指定的元素格式所截去。忽略它则由最近的日期截去下面是该函数的使用情...
使用SQL语句清空数据库所有表的数据
作者:李艳庆
近来发现数据库过大,空间不足,因此打算将数据库的数据进行全面的清理,但表非常多,一张一张的清空,实在麻烦,因此就想利用SQL语句一次清空所有数据.找到了三种方法进行清空.使用的数据库为MS
SQL SERVER.
1.搜索出所有
<br />1 trunc(value,precision)按精度(precision)截取某个数字,不进行舍入操作。<br />
2 round(value,precision)根据给定的精度(precision)输入数值。<br />
3 ceil (value) 产生大于或等于指定值(value)的最小整数。<br />
4 floor(value)与 ceil()相反,产生小于或等于指定值(value)的最小整数。<br />
5 sign(value)
与绝对值函数ABS()相反。ABS