Slow Postgres updates if OTHER columns are indexed?
We're not creating more data, so existing data shouldn't need to be moved around on the HDD, it just needs to be overwritten


That's not the case.

In order to support rollback and crash-safety, PostgreSQL must write a new copy of every modified row, rather than modifying the row in-place. Twice, actually, because it must be written to WAL (a sequential log for crash recovery) then to the table.

PostgreSQL's autovacuum then comes along later and marks the old row versions as free space that can be re-used.

See the user manual for more information on concurrency control and MVCC.


  the data is not changing size (e.g., rewriting a boolean value)


Irrelevant, because the row must be rewritten anyway.


  only one column is being updated, and it is non-indexed
  there are indexes on other columns  


This only matters insofar as it affects HOT updates, where PostgreSQL can potentially avoid writing new index entries for a row update if no indexed columns are modified and there's enough free space on the same disk page (8k block) to store a new copy of the row.


  Why do indexes on columns irrelevant to this query balloon the update time?


In most cases PostgreSQL must add new index entries even if you didn't modify indexed columns, because it has to write a new version of the row to a separate database page.

Setting a FILLFACTOR of 50 or less can help with this, as it encourages PostgreSQl to keep more free space for updates, at the cost of scans having to read and process more data.