Why does DELETE leave a lingering effect on performance?
-
30-10-2019 - |
Question
At the end is a test script for comparing the performance between a @table variable and a #temp table. I think I've set it up correctly - the performance timings are taken outside of the DELETE/TRUNCATE commands. The results that I am getting are as follows (times in milliseconds).
@Table Variable #Temp (delete) #Temp (truncate)
--------------- -------------- ----------------
5723 5180 5506
15636 14746 7800
14506 14300 5583
14030 15460 5386
16706 16186 5360
Just to make sure I'm sane, this shows that CURRENT_TIMESTAMP (aka GetDate()
) is taken at the time of the statement, not of the batch, so there should be no interaction between TRUNCATE/DELETE with the SET @StartTime = CURRENT_TIMESTAMP
statement.
select current_timestamp
waitfor delay '00:00:04'
select current_timestamp
-----------------------
2012-10-21 11:29:20.290
-----------------------
2012-10-21 11:29:24.290
It's quite consistent in the jump between the first run and the subsequent runs when DELETE is used to clear the table. What am I missing in my understanding of DELETE? I have repeated this many times, swapped the order, sized tempdb to not require growth etc.
CREATE TABLE #values (
id int identity primary key, -- will be clustered
name varchar(100) null,
number int null,
type char(3) not null,
low int null,
high int null,
status smallint not null
);
GO
SET NOCOUNT ON;
DECLARE @values TABLE (
id int identity primary key clustered,
name varchar(100) null,
number int null,
type char(3) not null,
low int null,
high int null,
status smallint not null
);
DECLARE @ExecutionTime TABLE( Duration bigINT )
DECLARE @StartTime DATETIME, @i INT = 1;
WHILE (@i <= 5)
BEGIN
DELETE @values;
DBCC freeproccache With NO_InfoMSGS;
DBCC DROPCLEANBUFFERS With NO_InfoMSGS;
SET @StartTime = CURRENT_TIMESTAMP -- alternate getdate()
/****************** measured process ***********************/
INSERT @values SELECT a.* FROM master..spt_values a join master..spt_values b on b.type='P' and b.number < 1000;
/**************** end measured process *********************/
INSERT @ExecutionTime
SELECT DurationInMilliseconds = datediff(ms,@StartTime,CURRENT_TIMESTAMP)
SET @i += 1
END -- WHILE
SELECT DurationInMilliseconds = Duration FROM @ExecutionTime
GO
-- Temporary table
DECLARE @ExecutionTime TABLE( Duration bigINT )
DECLARE @StartTime DATETIME, @i INT = 1;
WHILE (@i <= 5)
BEGIN
delete #values;
-- TRUNCATE TABLE #values;
DBCC freeproccache With NO_InfoMSGS;
DBCC DROPCLEANBUFFERS With NO_InfoMSGS;
SET @StartTime = CURRENT_TIMESTAMP -- alternate getdate()
/****************** measured process ***********************/
INSERT #values SELECT a.* FROM master..spt_values a join master..spt_values b on b.type='P' and b.number < 1000;
/**************** end measured process *********************/
INSERT @ExecutionTime
SELECT DurationInMilliseconds = datediff(ms,@StartTime,CURRENT_TIMESTAMP)
SET @i += 1
END -- WHILE
SELECT DurationInMilliseconds = Duration FROM @ExecutionTime
GO
DROP TABLE #values
SET NOCOUNT OFF;
No correct solution