Reputation: 8806
I need to delete entries from two tables, using some ids
found from a unique SELECT
query.
What is the most performant way of doing this using SQL Server?
I currently use a Table Variable
:
DECLARE @emailIdsToDelete TABLE(id int NOT NULL);
INSERT INTO @emailIdsToDelete
SELECT id
FROM ...;
DELETE organisations_emails
FROM @emailIdsToDelete etd
INNER JOIN ...;
DELETE emails
FROM @emailIdsToDelete etd
INNER JOIN ...;
But since I need that table only to store the result of the SELECT
, and only for the scope of this specific query, I was wondering if there was a more performant solution.
I think I can't use CTE
(using the "with()
" clause) since it allows only one following statement, not two.
Is there a way to delete from those two tables, without having to create a temporary table first? Some kind of join
? Or is my solution already optimal?
UPDATE : Let's say there is no "ON DELETE CASCADE
" between any of those tables.
Upvotes: 1
Views: 94
Reputation: 363
Cascade Delete
is an option, however you would need to test to validate it is more performant, also sometimes even with FKs this can leave orphans records.
Soft Delete
You could add a isDeleteFlag
column set it to bit default(0)
and update it to 1 when you run your query, again would have to test it. If you wanted to stop there you would need to change your usp_ to accommodate not to return these records. where isDeleteFlag = 0
To follow up with the most performant, you could use the soft delete and then at night do smaller batches of deletes, or you could store the delete ids in a separate table and remove them at night in batches. This might work for you depending on what you are trying to accomplish, if it is okay to steal performance at night rather than during normal business operations, sometimes it's not viable.
In the end the answer is it depends and mileage will vary, you'll need to test the solutions to compare performance.
Optionally you could use your approach and use a variable table / temp table or a user defined table type.
Edit: Also you could output the deleted ids and daisy chain deletes in a transaction.
Upvotes: 1
Reputation: 16853
The other way would be to have a foreign key between organisations_emails
and emails
with ON DELETE CASCADE
. Then you would merely need to delete from emails
, and matching rows in organisations_emails
would be deleted automatically.
Assuming that the foreign key is appropriate in your schema, of course.
Upvotes: 1