When I do this (in batches) I wonder if the selection criteria (i.e. "like 'SIC%'" in your case) takes time on each iteration of the loop.
I get all the clustered index keys into a #temporary table, ordered by those keys, with an IDENTTIY column, and then delete in batches based on ranges of the ID. Something like this:
SELECT IDENTITY(int, 1, 1) AS MyID, ClustKey1, ClustKey2, ...
INTO #TEMP
FROM F_POLICY_TRANSACTION
WHERE [POLICY_TRANSACTION_BKEY] like 'SIC%'
ORDER BY ClustKey1, ClustKey2, ...
DECLARE@intLoop int = 1
WHILE 1 = 1
BEGIN
DELETE D
FROM #TEMP AS T
JOIN F_POLICY_TRANSACTION AS D
ON D.ClustKey1 = T.ClustKey1
AND D.ClustKey2 = T.ClustKey2
AND ...
WHERE T.ID BETWEEN @intLoop AND @intLoop + 50000
IF @@ROWCOUNT < 50000 BREAK;
SELECT @intLoop = @intLoop + 50000
END
I'd be interested to hear if that is any more efficient for you.