Delete statement in SQL is very slow
Things that can cause a delete to be slow:
- deleting a lot of records
- many indexes
- missing indexes on foreign keys in child tables. (thank you to @CesarAlvaradoDiaz for mentioning this in the comments)
- deadlocks and blocking
- triggers
- cascade delete (those ten parent records you are deleting could mean
millions of child records getting deleted) - Transaction log needing to grow
- Many Foreign keys to check
So your choices are to find out what is blocking and fix it or run the deletes in off hours when they won't be interfering with the normal production load. You can run the delete in batches (useful if you have triggers, cascade delete, or a large number of records). You can drop and recreate the indexes (best if you can do that in off hours too).
Very slow DELETE query
Add a Primary key to your table variables and watch them scream
DECLARE @IdList1 TABLE(Id INT primary Key not null)
DECLARE @IdList2 TABLE(Id INT primary Key not null)
because there's no index on these table variables, any joins or subqueries must examine on the order of 10,000 times 10,000 = 100,000,000 pairs of values.
SQL Delete a single row by PK is very slow
I dropped and re-created all Foreign Keys with NO cascade delete.
Now the execution plan is using efficient Index Seeks to check RI on all FKs.
Not sure why having cascade delete enabled caused these Index Scans though...
Why delete rows seems to be slow in SQL Server?
This is an apples to oranges comparison, since a DELETE
is writing to the transaction log and SELECT
is not.
The DISTINCT
works by virtue of sorting the output rows in order to find duplicates. This will be made really slow if you are missing an index (for what it's worth 3 seconds seems slow to me for output). Even slower when performing a NOT IN
on the same column. This doesn't take into consideration any constraints you might have on that column, which could further slow it down.
You can likely make this faster using GROUP BY
.
DELETE
FROM [DBName].[dbo].[index]
WHERE family NOT IN (
SELECT family
FROM [DBName].[dbo].[student]
GROUP BY family)
Likely faster still using NOT EXISTS
instead of NOT IN
:
DELETE
FROM [DBName].[dbo].[index] AS outer
WHERE family NOT EXISTS (
SELECT family
FROM [DBName].[dbo].[student] AS inner
WHERE inner.family = outer.family
GROUP BY family)
Delete statement was very slow in Oracle
There can be many reasons:
- Server load (unlikely because the
SELECT
is fast) - Triggers (see here how to list them for a table).
- Foreign keys (List of foreign keys and the tables they reference)
- A lot of data in each row (
LOB
s, many columns). - Someone is locking rows in the table that you'd like to delete (or the whole table). See this blog post how to list locks. This discussion might also help.
If the foreign keys are the problem, the usual solution is to add indexes on the foreign column: For each delete, Oracle needs to check whether this would violate a foreign key relation.
Related Topics
SQL Query to Bring Last Letter in a String to First Letter Position
Splitting a Comma-Separated Field in Postgresql and Doing a Union All on All the Resulting Tables
Mongodb and Postgresql Thoughts
Understanding the Differences Between Cube and Rollup
SQL Query for Finding a Value in Multiple Ranges
Postgresql Constraint - Only One Row Can Have Flag Set
Oracle Delete Rows Matching on Multiple Values
How to Perform a Left Join in SQL Server Between Two Select Statements
Differencebetween Postgres Distinct VS Distinct On
Just Get Column Names from Hive Table
Percentage from Total Sum After Group by SQL Server
Lock Escalation - What's Happening Here
A Procedure to Reverse a String in Pl/Sql
Get Table and Index Storage Size in SQL Server
Sql: When It Comes to Not in and Not Equal To, Which Is More Efficient and Why
Returning the Distinct First Character of a Field (Mysql)