| A note about count(1) vs count(* ). One might think that count(1) would be faster because count(* ) appears to consult the data for a whole row. However the opposite is true. Which is the opposite decision of other databases. So sometimes Postgres does make bad decisions...
I think the "the opposite is true" is in reference to the assertion that "count(⧆) appears to consult the data for a whole row", not to the proposition that "one might think that count(1) would be faster [than count(⧆)]". count(⧆) just counts the tuples themselves, which is fast; it's like counting heap-allocated data structures by counting their pointers (which you're already walking), without dereferencing those po…
PostgreSQL Count(*) Performance Improvements
21–30 of 35 posts
Re: PostgreSQL Count(*) Performance Improvements
#22Note the trigger approach mentioned in the article would be terrible for performance in a concurrent environment, since only one transaction could modify the whole table at a time.
I wonder if there's a way to "shard" these counters to avoid this problem. If you had 10 different counters (maybe in ten different tables) and a mechanism for round-robin or randomly selecting which counter gets incremented/decremented would that allow ten concurrent transactions at once? The query to return the total count would then need to sum the 10 individual counters, which should be extremely fast. Or is the…
Re: PostgreSQL Count(*) Performance Improvements
#23Earlier quoted context omitted.
I wonder if there's a way to "shard" these counters to avoid this problem. If you had 10 different counters (maybe in ten different tables) and a mechanism for round-robin or randomly selecting which counter gets incremented/decremented would that allow ten concurrent transactions at once? The query to return the total count would then need to sum the 10 individual counters, which should be extremely fast. Or is the…
Even though only 1 / 10 counters would be locked, you'd still have to read all 10 to get the count, which would be blocked until the concurrent transaction ended.
Re: PostgreSQL Count(*) Performance Improvements
#24Note the trigger approach mentioned in the article would be terrible for performance in a concurrent environment, since only one transaction could modify the whole table at a time.
I wonder if there's a way to "shard" these counters to avoid this problem. If you had 10 different counters (maybe in ten different tables) and a mechanism for round-robin or randomly selecting which counter gets incremented/decremented would that allow ten concurrent transactions at once? The query to return the total count would then need to sum the 10 individual counters, which should be extremely fast. Or is the…
Re: PostgreSQL Count(*) Performance Improvements
#25Given the title, I expected this to be about how PG improved their counting. This is not what it was about. I remember working over half a billion records and having problems when I needed a count. I used count(id) but that was mainly from internet mantra. I did not see an improvement. Using Citus gave me a significant improvement from 7 minutes to 1. And that was just a single coordinator, two workers on the same ho…
Re: PostgreSQL Count(*) Performance Improvements
#26On the one hand, I think that is great. On the other hand, I am still suspicious.
Re: PostgreSQL Count(*) Performance Improvements
#27| A note about count(1) vs count(* ). One might think that count(1) would be faster because count(* ) appears to consult the data for a whole row. However the opposite is true. Which is the opposite decision of other databases. So sometimes Postgres does make bad decisions...
I think the "the opposite is true" is in reference to the assertion that "count(⧆) appears to consult the data for a whole row", not to the proposition that "one might think that count(1) would be faster [than count(⧆)]". count(⧆) just counts the tuples themselves, which is fast; it's like counting heap-allocated data structures by counting their pointers (which you're already walking), without dereferencing those po…
count( * ) is faster on Postgres than count(1). But both are fundementally slow because of MVCC. And count( * ) on postgres (the optimized one on Postgres) is much slower than count(1) on other databases (the optimzed one on other databases). So practically speaking, counting rows is slower on Postgres than on other databases.
That said, I love Postgres. I use it every day. There is some room for improvement and it does improve all the time. It is an amazing open source project. And I wouldn't care at all if they never optimize count(1)
Re: PostgreSQL Count(*) Performance Improvements
#28For me, the trick to basic understanding of perf in PG was exactly this: it is all about limiting the amount of rows you have to iterate over. It is true for count() but also for every other operation you do.
PG is surprisingly non-magical (at least in my experience) in that you won't get much perf for free, but on the other hand you can reason about perf & optimize pretty reliably once you come to terms with this.
Re: PostgreSQL Count(*) Performance Improvements
#29Sorry for being a bit off topic, but anyone out there who is using PostgreSQL in production, how do you manage tables with lots of updates? Is auto-vacuum doing good enough job for you or do you have to run “vacuum full” regularly?
Eg
Create table (...) with (fillfactor=30)
https://www.postgresql.org/docs/current/sql-createtable.html
Re: PostgreSQL Count(*) Performance Improvements
#30Sorry for being a bit off topic, but anyone out there who is using PostgreSQL in production, how do you manage tables with lots of updates? Is auto-vacuum doing good enough job for you or do you have to run “vacuum full” regularly?
The extension essentially creates a new table without the block and replaces the original one, keeping track of changes to the table using trigger; so the exclusive lock of VACUUM FULL is not needed for quite the long time.