The main problem is string concatenation operator as called out in the other answers and comments. However, the concatenation method prevents a sargable expression so indexes on the columns cannot be used efficiently. This is very bad for concurrency since the DELETE will need to perform a full scan, touching all rows in the table instead of only those that are needed.
You could refactor the query to use EXISTS
to allow efficient index use and specify table aliases to avoid ambiguity:
DELETE FROM swi
WHERE EXISTS(
SELECT 1
FROM swi AS a
WHERE a.co = swi.co
AND a.na = swi.na
AND NOT EXISTS (
SELECT 1
FROM swi_tmp AS b
WHERE
b.co = swi.co
AND b.na = swi.na
)
);
And better, remove the redundant EXISTS
, which will be true for all rows anyway (except NULL
values):
DELETE FROM swi
WHERE NOT EXISTS (
SELECT 1
FROM swi_tmp
WHERE
swi_tmp.co = swi.co
AND swi_tmp.na = swi.na
);
Note that saragable expressions will improve performance in all RDBMS products, not just SQL Server, and are a best practice.