Question: In general it's necessary to delete about 110K rows from table `Nodes` but their id are not declared explicitly but are given from another table.

```
DECLARE @gh Table(id int);
INSERT INTO @gh (id) SELECT node_id FROM Relations;
DELETE FROM Nodes WHERE id NOT IN (SELECT DISTINCT id FROM @gh)

```

Selection (`SELECT DISTINCT id FROM @gh`) contains about 20K rows and server couldn't delete them due to expired timeout. What other ways to do it are there?

Answer: 
If you're keeping 20k of 130k, I'd do it a different way

```
SELECT N.* 
  INTO #NodesTemp 
FROM  
  Relations R JOIN Nodes N ON R.id = N.id;

TRUNCATE TABLE Nodes;

INSERT Nodes SELECT * FROM #NodesTemp;

DROP TABLE #NodesTemp;

```

Edit:

* do you have a DELETE trigger on Nodes?
* do you have foreign keys to Nodes that need checked?
You can try deleting the nodes in batches instead of all at once by adding a TOP clause to DELETE:

```
WHILE EXISTS(SELECT * FROM Nodes WHERE id NOT IN (SELECT DISTINCT id FROM @gh))
DELETE TOP (100) Nodes
WHERE id NOT IN (SELECT DISTINCT id FROM @gh)

```