Postgres performance analysis resulted in a 10x improvement in CPU use
blog.heapanalytics.com
blog.heapanalytics.com
This is write performance optimization 101. I bet you are getting wins in way more places in the pipeline than the evaluation pointed to by doing this.
Try doing the same optimization on a table with zero partial indexes and you will get the same 10x bump. It is better for many many reasons.
Still, super cool dig into performance tools and source code. It shows great aptitude and willingness to deep dive.
There are a million 'db best practices' you can go implement blindly, but the point is that this methodology – determining the bottlenecking resource and then profiling to determine exactly what is consuming it – will _reliably_ yield huge wins, whereas implementing 'best practices' on gut alone is a very inefficient way to improve performance.
Without any specific numbers backing up the 10x we can only guess what improved 10x. All of those things you listed show up as CPU wait events as well. Without specifics I assume he means they inserted the same row count in 1/10th of the time. Not that there was a direct drop in CPU tasks.
As for the numbers, we specifically got a 10x improvement in ingestion throughput.
Often the saving on roundtrips is bigger than any of these. Most database client libraries work synchronously, so if you insert via single row INSERT statements you'll approximately get a two context switches, and a roundtrip for each row. That's often more costly wall clock time wise than the insertion itself.
It's usually amazing how much more you can squeeze out of your database if you just take a deep look inside. Often times, you'd be surprised what it's actually doing...
Related / Further reading:
"Debugging PostgreSQL performance, the hard way"
I've seen two examples recently where a potentially impactful optimisation was added to a product but it didn't actually work as intended because of minor errors. It took a couple of years before the performance bugs were found, which required several hours of work.
In the first, a O(n) algorithm was replaced with a O(log n) version, but part of it remained O(n) for a subtle reason. The code was still faster by a constant factor so it wasn't totally obvious. In that case validating that the algorithm was actually O(log n) by doing some experiments for larger values of n would have revealed runtime was increasing linearly.
In the second, an optional argument was added to a method that triggered an optimisation for a particular case, but it was never passed in at any callsites. In that case many different tests could have revealed that the optimisation wasn't effective or that the new code wasn't even running.
That is the real takeaway from the article.
Making assumptions is fine, making assumptions and not immediately verifying whether they hold or not is not.
This is why it is super important to actually write down your assumptions and test them one-by-one when implementing some solution. More often than not you'll find that there is some light between what you thought was true and what is really happening.
So this is much more a systemic problem than just a database tuning problem.
INSERT INTO table (columns...)
VALUES
(row 1...),
(row 2...),
...
An alternative and potentially faster method is using the COPY FROM statement.[0] https://www.postgresql.org/docs/9.5/static/sql-explain.html