Sqlserver can not use delete top from procedure
Say you’ve got a table with millions or billions of rows, and you need to delete some rows. Deleting ALL of them is fast and easy – just do TRUNCATE TABLE – but things get much harder when you need to delete a small percentage of them, say 5%. Show It’s especially painful if you need to do regular archiving jobs, like deleting the oldest 30 days of data from a table with 10 years of data in it. The trick is making a view that contains the top, say, 1,000 rows that you want to delete: CREATE VIEW dbo.Comments_ToBeDeleted AS SELECT TOP 1000 * FROM dbo.Comments ORDER BY CreationDate; GO Make sure that there’s an index to support your view: CREATE INDEX IX_CreationDate ON dbo.Comments(CreationDate); And then deleting from the view, not the table: DELETE dbo.Comments_ToBeDeleted WHERE CreationDate < '2010-01-01'; This lets you nibble off deletes in faster, smaller chunks, all while avoiding ugly table locks. Just keep running the DELETE statement until no rows are left that match. It won’t necessarily be faster overall than just taking one lock and calling it a day, but it’ll be much more concurrency-friendly. Wanna see it in action? No? Then just copy/paste my code, put it straight into production like you always do, and get back to work. For the rest of you, keep reading. Demoing Fast Ordered DeletesTo demo this technique, I’m going to use the cloud setup for our Mastering Query Tuning classes:
The Comments table has a CreationDate field, and let’s say I need to delete the oldest comments – we’re going to delete all the ones from 2008 and 2009: Comments by year2008 & 2009 had a total of 1,387,218 comments – but that’s only about 2.3% of the table’s overall rows. First, the plain ol’ DELETE.I could try just deleting them outright: DELETE dbo.Comments WHERE CreationDate < '2010-01-01'; It takes 39 seconds. Here’s what the actual execution plan (PasteThePlan) looks like: DELETE dbo.Comments WHERE CreationDate < ‘2010-01-01’It’s what we call a “wide” execution plan, something I first heard from Bart Duncan’s post and then later Paul White explained in much more detail. Because we’re deleting so many rows, SQL Server does a bunch of sorting, and those sorts even end up spilling to TempDB. Plus, it’s taking a big table lock as it works. That’s no good, especially on big tables. If you can get away with a 39-second table lock and activity in TempDB, the plain ol’ DELETE technique is fine. But let’s pretend you’re working in a mission-critical environment where a 39-second table lock is out of the question, and you need a faster background technique. Demoing Fast Ordered DeletesLike we talked about at the start of this odyssey, create a view: CREATE VIEW dbo.Comments_ToBeDeleted AS SELECT TOP 1000 * FROM dbo.Comments ORDER BY CreationDate; GO Make sure that there’s an index to support your view: CREATE INDEX IX_CreationDate ON dbo.Comments(CreationDate); And then deleting from the view, not the table: DELETE dbo.Comments_ToBeDeleted WHERE CreationDate < '2010-01-01'; It runs nearly instantly (because we’ve got an index to support it), and here’s the plan: At first, it looks the same as the plain DELETE plan, but look closer, and there’s something missing: Just like me with the tequila – no spillsThere’s no yellow bangs because there’s fewer sort operators and they’re not spilling to disk. Similarly, the memory grant on this query is way lower:
The grants are lower because we’re handling less data, which is also evidenced by the STATISTICS IO output:
If you need to do this regularly, tune it.You can play around with:
That way you can find the sweet spot for your own deletes based on your server’s horsepower, concurrency demands from other queries (some of which might be trying to take table locks themselves), the amount of data you need to delete, etc. Use the techniques Michael J. Swart describes in Take Care When Scripting Batches. For more learning on this topic, read Microsoft SQLCat on Fast Ordered Deletes – Wayback machine copy because Microsoft deleted a lot of pages during one of their annual corporate shuffles. You can tell it’s old because…MySpace, yeah. Can we use DELETE with top in SQL?In SQL Server, DELETE TOP statement is used to delete the records from a table and limit the number of records deleted regarding a fixed value or percentage. Syntax: DELETE TOP (top_value) [ PERCENT ] FROM [database_name]. How to delete data from procedure in SQL?Use SQL Server Management Studio. In Object Explorer, connect to an instance of Database Engine and then expand that instance.. Expand Databases, expand the database in which the procedure belongs, and then expand Programmability.. Expand Stored Procedures, right-click the procedure to remove, and then select Delete.. How do I DELETE a top order in SQL Server?Example - Using TOP keyword Let's look at a SQL Server example, where we use the TOP keyword in the DELETE statement. For example: DELETE TOP(10) FROM employees WHERE last_name = 'Anderson'; This SQL Server DELETE TOP example would delete the first 10 records from the employees table where the last_name is 'Anderson'. Why i can't DELETE table in SQL?The reason SQL won't let you drop a table in this situation is because the allocation pages/extent chain appears to be damaged or cross-linked in some way. So SQL Server thinks that there is actually data from other tables in pages/extents belonging to the problem object. |