Why does using a variable make a difference in performance? I have a table that constantly doing insert, and I am trying to run a delete script to remove old record.

The delete script looks like this:

DECLARE @StarDate DATETIME = '2013-01-13';
DECLARE @DeleteTop Int = 2000

WHILE @@ROWCOUNT &lt;&gt; 0
BEGIN
    DELETE TOP (@DeleteTop) FROM VehicleLocation 
    WHERE 
    MessageGenerationDate &lt; @StarDate
    AND (NOT EXISTS 
    (SELECT NULL FROM VehicleLocationTP 
    WHERE VehicleLocationTP.VehicleLocationKey = VehicleLocation.VehicleLocationKey) 
    AND NOT EXISTS 
    (SELECT NULL FROM VehicleLocationGF WHERE VehicleLocationGF.VehicleLocationKey = VehicleLocation.VehicleLocationKey) 
    AND NOT EXISTS 
    (SELECT NULL FROM VehicleLocationInpt WHERE VehicleLocationInpt.VehicleLocationKey = VehicleLocation.VehicleLocationKey) 
    AND NOT EXISTS 
    (SELECT NULL FROM VehicleLocationFare WHERE VehicleLocationFare.VehicleLocationKey = VehicleLocation.VehicleLocationKey) 
    AND NOT EXISTS 
    (SELECT NULL FROM VehicleLocationOBD WHERE VehicleLocationOBD.VehicleLocationKey = VehicleLocation.VehicleLocationKey) 
    AND NOT EXISTS 
    (SELECT NULL FROM VehicleLocationAPC WHERE VehicleLocationAPC.VehicleLocationKey = VehicleLocation.VehicleLocationKey));
END;


When running this script, it causing LCK_M_IX wait type on the insert, causing the insert being blocked.

However, if I remove the variables, and simply go for

DELETE TOP (2000) FROM VehicleLocation...


I will no longer see the LCK_M_IX wait type.

What kind of optimization SQL-Server was trying to perform? Is it better to avoid using variables and instead specific the value explicit?

This question is related to a similar question: https://stackoverflow.com/questions/2293772/t-sql-query-performance-puzzle-why-does-using-a-variable-make-a-difference
Sometimes yes it's good to use statics.  In this case the SQL Server doesn't know what the value is in the variable when it's creating the plan so it's escalating to a table lock I'm guessing.  You could force the locks to be row locks on the delete statement which should fix the problem.