views:

83

answers:

2

I have a table with a few million tuples.

I perform updates in most of them.

The first update takes about a minute. The second, takes two minutes. The third update takes four minutes.

After that, I execute a VACUUM FULL.

Then, I execute the update again, which takes two minutes.

If I dump the database and recreate it, the first update will take one minute.

Why doesn't PostgreSQL performance get back to its maximum after a VACUUM FULL?

+2  A: 

The order of the tuples might be different, this results in different queryplans. If you want a fixed order, use CLUSTER. Lower the FILLFACTOR as well and turn on auto_vacuum. And did you ANALYZE as well?

Use EXPLAIN to see how a query is executed.

Frank Heikens
@Frank Heikens, I update all tuples, there are some flags that are marked to classify them. The time spent is in this update. Whem I re-run the update, there's a slow down
pcent
@Frank Heikens, I've found this question you answered last week, it clarified my ideashttp://stackoverflow.com/questions/3100072/postgresql-slow-on-a-large-table-with-arrays-and-lots-of-updates/3100232#3100232
pcent
Running REINDEX TABLE can also be a good idea after a VACUUM FULL.
Matthew Wood
Also, since this is an update activity, you will have no empty pages to use after a vacuum full, forcing the system to allocate more space. Often, if activity will remain high, and your free pages do exceed the size of the free space map, a regular vacuum does more for performance than a vacuum full.
Grant Johnson
+2  A: 

VACUUM FULL does not compact the indexes. In fact, indexes can be in worse shape after performing a VACUUM FULL. After a VACUUM FULL, you should REINDEX the table.

However, VACUUM FULL+REINDEX is quite slow. You can achieve the same effect of compacting the table and the indexes using the CLUSTER command which takes a fraction of the time. It has the added benefit that it will order your table based on the index you choose to CLUSTER on. This can improve query performance. The downsides to CLUSTER over VACUUM FULL+REINDEX is that it requires approximately twice the disk space while running. Also, be very careful with this command if you are running a version older than 8.3. It is not MVCC safe and you can lose data.

Also, you can do a no-op ALTER TABLE ... ALTER COLUMN statement to get rid of the table and index bloat, this is the quickest solution.

Finally, any VACUUM FULL question should also address the fact why you need to do this? This is almost always caused by incorrect vacuuming. You should be running autovacuum and tuning it properly so that you never have to run a VACUUM FULL.

Brad Nicholson