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

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top