I have a Postgres table with a large number of indexed columns (roughly 100 indexed columns total, and yes, I need them all, and yes, they all need to be separately indexed). Any row update causes all indexes to be updated, which is a lot of work for the DB engine.
I want to understand the concurrency implications of the discussion on the Postgres documentation page titled Index Locking Considerations, and also the fact that Postgres is single-threaded (multi-process), in terms of how the current design affects reader and writer performance for a large number of concurrent queries, given that I have so many column indices.
My interpretation of these things are the following (please correct any that are wrong):
- Writers that are updating individual rows don't block readers, unless the reader is running a query that produces a result set that would include the row that is being updated.
- Writers only block each other if they are trying to update the same row at the same time.
- Concurrent updates to btree-based indices from multiple writers get merged according to a set of rules that generally does the right thing (so updating the same indexes at the same time does not cause writers to block, unless they are updating the same row).
My questions are:
- How can there even be multiple concurrent readers or writers, if Postgres is single-threaded? If you have multiple processes running, do they simply rely on the inter-process consistency of disk caches (or have to manually flush contents to disk) to coordinate concurrent updates?
- What if anything can get blocked while a large number of indexes are being updated due to a row update? If anything can get blocked during an update, is it possible to turn a dial on the consistency-vs-availability tradeoff so that, for example, a row update is not atomic (i.e. so that the indexes are updated one at a time, but the update to all indexes doesn't have to happen atomically)? I'm OK with a lack of consistency in the name of higher concurrency.