Question

Using SqlServer2012, Is there any advantage in calling

if exists (select * from tablename where condition) begin
   delete tablename where condition
end

over just calling

   delete tablename where condition

When there often won't be any rows matching condition?

In particular, will it result in any fewer (or less restrictive) locks being held?

I am in an appropriate transaction, so I avoid race conditions.

Était-ce utile?

La solution

SQL Server can't collapse the two statements and only perform the locks once. But that's easy to prove, in any case. Let's make a copy of an AdventureWorks table, perform your two types of operations, and compare the locks taken. You will see that your approach where you check first performs about twice as many locks - you can check this by splitting the two portions of the output into separate files and doing any kind of diff against them (or just compare the size - in my case 1.7 MB vs. 788 KB).

SELECT * INTO dbo.kablatz
  FROM AdventureWorks2012.Sales.SalesOrderHeader;

SET NOCOUNT ON;

DBCC FREEPROCCACHE WITH NO_INFOMSGS;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;

PRINT '---------------- Check first';

DBCC TRACEON(1200,3604,-1) WITH NO_INFOMSGS;

IF EXISTS (SELECT 1 FROM dbo.kablatz WHERE OrderDate < '20100101')
  DELETE dbo.kablatz WHERE OrderDate < '20100101';

DBCC TRACEOFF(1200,3604,-1) WITH NO_INFOMSGS;

DBCC FREEPROCCACHE WITH NO_INFOMSGS;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;

PRINT '---------------- Don''t check first';

DBCC TRACEON(1200,3604,-1) WITH NO_INFOMSGS;

DELETE dbo.kablatz WHERE OrderDate < '20100101';

DBCC TRACEOFF(1200,3604,-1) WITH NO_INFOMSGS;

GO
DROP TABLE dbo.kablatz;

Logic will tell us that the checking for rows to delete already happens in the delete operation. Why repeat it?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top