0

I have this T-SQL that works just fine and it executes about 30 seconds.

DECLARE @BatchSize int = 1000, 
        @TransactionInterval tinyint = 5, 
        @MaxToDelete int = 10000, 
        @FactDeleted int = 0;
DECLARE @counter int = 1;
DECLARE @s datetime, 
        @e datetime, 
        @r int = 1;

SET @e = '20200606';

SELECT 
    @s = MIN(AtTime) 
FROM 
    dbo.DevicePositions;

BEGIN TRANSACTION;

WHILE (@r > 0) 
BEGIN 
    IF @r % @TransactionInterval = 1 
    BEGIN 
        COMMIT TRANSACTION;
        BEGIN TRANSACTION;
    END 

    DELETE TOP (@BatchSize) 
    FROM DevicePositions 
    WHERE AtTime >= @s 
      AND AtTime <= @e;

    SET @FactDeleted = @FactDeleted + @BatchSize;
    SET @r = @@ROWCOUNT;
    SET @counter = @counter + 1;

    IF @FactDeleted >= @MaxToDelete 
        BREAK;
END 

IF @@TRANCOUNT > 0 
BEGIN 
    COMMIT TRANSACTION;

    IF @counter % 10 = 0 -- or maybe 100 or 1000
        BEGIN CHECKPOINT;
        END 
END 
GO 

SELECT 
    A.Records 
FROM 
    (SELECT 
         OBJECT_NAME(object_id) as ID, 
         SUM(row_count) AS Records 
     FROM 
         sys.dm_db_partition_stats 
     WHERE 
         object_id = OBJECT_ID('DevicePositions') 
         AND index_id < 2 
     GROUP BY 
         OBJECT_NAME(object_id)) A

I converted this code into a stored procedure and it won't complete so it runs forever.

The stored procedure:

ALTER PROCEDURE [dbo].[DeleteOldDevicePositions] 
    @MaxToDelete int , -- Max amount of records to delete
    @BatchSize int , -- it is
    @ToEndDate datetime -- Delete until this datetime
AS
BEGIN
 
    SET NOCOUNT ON;
   
    DECLARE @TransactionInterval tinyint = 5, @FactDeleted int = 0;
    DECLARE @counter int = 1;
    DECLARE @s datetime, @e datetime, @r int = 1;    
    SELECT @s = MIN(AtTime) FROM dbo.DevicePositions;
    BEGIN TRANSACTION;
    WHILE (@r > 0)
    BEGIN
      IF @r % @TransactionInterval = 1
      BEGIN
        COMMIT TRANSACTION;
        BEGIN TRANSACTION;
      END
      DELETE TOP (@BatchSize) FROM DevicePositions WHERE AtTime >= @s AND AtTime <= @ToEndDate;
      SET @FactDeleted = @FactDeleted +@BatchSize;
      SET @r = @@ROWCOUNT;
      SET @counter = @counter + 1;
      IF @FactDeleted >= @MaxToDelete 
         BREAK;
    END
    IF @@TRANCOUNT > 0
    BEGIN
      COMMIT TRANSACTION;
      IF @counter % 10  = 0  -- or maybe 100 or 1000
      BEGIN 
        CHECKPOINT; 
      END
    END 
     
    SELECT A.Records FROM (
            SELECT OBJECT_NAME(object_id) as ID, SUM(row_count) AS Records FROM sys.dm_db_partition_stats WHERE 
            object_id = OBJECT_ID('DevicePositions') AND index_id < 2
            GROUP BY OBJECT_NAME(object_id) ) A 
END

And I start it like

EXEC [dbo].[DeleteOldDevicePositions] 10000, 1000,  '20200606'

So it starts and has no end.

What did I miss?

Thank you!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
NoWar
  • 36,338
  • 80
  • 323
  • 498

2 Answers2

0

Thanks to Stored procedure hangs seemingly without explanation

I have used http://whoisactive.com/ to see that there is a rollback on that table.

So I used

exec sp_who
KILL 53 WITH STATUSONLY;  

And see that have to wait until it will be done.

NoWar
  • 36,338
  • 80
  • 323
  • 498
0

May be Parameter Sniffing is one of the reason for this Issue. Please have a look on the below Link.

https://blog.sqlauthority.com/2019/12/19/sql-server-parameter-sniffing-simplest-example/

Thiyagu
  • 1,260
  • 1
  • 5
  • 14