logoalt Hacker News

echoangletoday at 3:46 PM6 repliesview on HN

> And yes, it's a well-known trick for all major relational databases (not just Postgres) that if you want to delete 90% of rows from a large a table, it's much faster to just copy the rows you want to keep to a new table, run DROP TABLE on the old table, and rename the new table to the old table.

Dumb question but why does the optimizer not just do that in secret then? Seems like something that should be detectable with some heuristics.


Replies

crazygringotoday at 4:26 PM

Because what do you do if rows are being inserted in the original table, while the new table is having rows copied over? You'll get missing rows.

You can only do the DROP TABLE trick if you know nothing else is writing to the table at the same time. You know if that's the case, according to your business logic. The database has no idea.

The DROP TABLE trick effectively bypasses all the normal guarantees of data consistency. This is why it's so fast. But you have to know that that's a safe thing to do for your data.

show 1 reply
sgarlandtoday at 4:04 PM

I assume partly because that would be extremely surprising behavior, and depending on the RDBMS and version, could introduce unexpected stalls. For example, MySQL < 8.0.23 scans the entire buffer pool to clear pages that were dropped, which can take a long time on large instances. There is / was a similar issue with its adaptive hash index, which AFAIK wasn’t ever fixed, though AHI’s default being shifted to OFF in 8.4 is a workaround, in a very hacky way.

Retr0idtoday at 4:14 PM

Maintaining the expected observable behaviours would get complicated if queries (especially other updates) against the same table are happening concurrently.

layer8today at 6:10 PM

Because dropping a table effectively requires an exclusive lock on the table during that whole operation, affecting parallel transactions.

mordaetoday at 3:53 PM

It drops dependents.