30 tables with few rows - TRUNCATE the fastest way to empty them and reset attached sequences?

别说谁变了你拦得住时间么 提交于 2019-12-06 23:42:27

PostgreSQL can truncate many tables in a single TRUNCATE TABLE statement. Don't bother iterating and just do

TRUNCATE TABLE table1,table2,table3,...,table30;
Craig Ringer

See also:

Postgresql Truncation speed

for discussion of why truncation can be slower on Pg, and why DELETE isn't the same thing.

As requested in the comment
(although I don't feel this is the right answer - but it's too long for a comment)

There is no (noticable) performance difference between truncating an empty table or truncating a large table.

As stated in the manual (http://www.postgresql.org/docs/current/static/sql-truncate.html) "it does not actually scan the tables"

So if you first check if there are any rows in the table, you will scan the table. Something that won't happen if you simply issue the truncate without bothering whether

[I don't know RoR]

A nice way to start with a clean slate is to create and use a temp SCHEMA:

DROP SCHEMA fuzz CASCADE;
CREATE SCHEMA fuzz;
SET search_path='fuzz';

(this is what I use to test sql snippets). But this would create an empty schema, and you cannot copy schemas, IFAIK.

The other way would be to create your database (including the empty tables) and use that as a template for constructing the test-rig:

DROP DATABASE testdb;
CREATE DATABASE testdb TEMPLATE my_spcial_template;

The problem with that is, that you cannot drop the database if there are still connections to it (such as the drop-process itself) So, your front-end should first disconnect, than temporarily connect to some other DB (such as my_spcial_template) , than dropdb+createdb, than connect testdb. I don't know about performance, but at least it is a robust scheme.

If someone is interested with the current strategy, I use for this, see this Ruby-based repo https://github.com/stanislaw/truncate-vs-count for both MySQL and PostgreSQL.

My results:

MySQL: the fastest strategy for cleaning databases is truncation with following modifications:

if table is not empty
  truncate. 
else 
  if AUTO_INCREMENT is not 0
    truncate.
  end
end
  • For MySQL just truncation is much faster than just deletion. The only case where DELETE wins over TRUNCATE is doing it on empty table.
  • For MySQL truncation with empty checks is much faster than just multiple truncation.
  • For MySQL deletion with empty checks is much faster than just DELETE on each tables.

PostgreSQL: The fastest strategy for cleaning databases is deletion with the same empty-checks as for MySQL, but with relying on currval instead:

if table is not empty
  delete table
else 
  if currval is not 0
    delete table
  end
end
  • For PostgreSQL just deletion is much faster than just TRUNCATION(even multiple).
  • For PostgreSQL multiple TRUNCATE doing empty checks before is slightly faster than just multiple TRUNCATE
  • For PostgreSQL deletion with empty checks is slightly faster than just PostgreSQL deletion.

This is from where it began: https://github.com/bmabey/database_cleaner/issues/126

This is the result code and long discussion: https://github.com/bmabey/database_cleaner/pull/127

This is discussion on pgsql-performance mailing list: http://archives.postgresql.org/pgsql-performance/2012-07/msg00047.php

We began collecting users feedback proving my idea with first checking empty tables is right.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!