Wednesday, April 26, 2023

Time to compile Postgres, MySQL and MyRocks

I measured the time it takes to build Postgres, upstream MySQL and FB MySQL from source on my home servers (Beelink, see here) using Postgres 15.2, upstream MySQL 8.0.32 and FB MySQL 8.0.28. 


  • Build times in seconds: 619 for Postgres, 5294 for upstream MySQL, 8443 for FB MySQL
  • Postgres is by far the fastest to compile. Reasons for that include that it uses C and has fewer things to compile
  • FB MySQL spends ~2700 seconds compiling RocksDB related things. Without that overhead the FB MySQL build would be 5601 seconds vs 5294 for upstream MySQL. For reasons I don't understand yet, most of the RocksDB source files are compiled 3 times (for the storage engine, ldb binary and sst_dump binary). If that could be avoided then the build time would be reduced by ~20%.


While the server has 8 cores I did a non-parallel make (make -j1). 

The build configuration (configure & CMake command lines) for each DBMS is here.


For Postgres I just measure the total time to build. For upstream and FB MySQL I also measure the time for each build target. That is done in two steps.

  1. Run make and add timestamps to the output. Smart people on Twitter explained how to do that.
  2. Parse the output from make to get per-target compile times
To run make I did:
make 2>&1 | ts '[%s]' | tee o.time
To parse the output I did:
grep "Built target" o.time | tr '[]' ' ' | \
awk '{ $2=""; $3=""; $4=""; print $0 }' | \
awk '{ if (NR==1) { printf "%s\t%s\n", $1 - itime, $2 } else { printf "%s\t%s\n", $1 - lastTS, $2 };  lastTS=$1 } ' itime=$firstTS | \
sort -rnk 1,1 | head -10
Results: summary


* Time(s) - total time for build in seconds
* Targets - number of build targets, only printed for MySQL

Time(s) Targets DBMS
619     NA      Postgres
5294    255     upstream MySQL
8443    251     FB MySQL

Results: detailed

The time in seconds for the top-20 build targets

For upstream MySQL 8.0.32:

1035    sql_main
636     innobase
433     sql_gis
393     sql_dd
301     group_replication
294     perfschema
209     icui18n
190     mysqld
153     libprotoc
128     icuuc
123     libprotobuf
99      slave
96      binlog
65      mysql_server_component_services
65      mysqlgcs
54      mysys_objlib
49      myisam_library
44      mysqlpump_lib
33      libprotobuf-lite
30      mysqlbinlog


The RocksDB related build targets are rocksdb_se, ldb and sst_dump. From the output it looks like each of those repeats the same work -- as all or most of the RocksDB source files are recompiled for each. That explains why each target takes ~900 seconds. If the recompile could be avoided then the build time would be reduced by ~20%.

1201    sql_main
993     rocksdb_se
932     ldb
917     sst_dump
598     innobase
462     sql_dd
411     sql_gis
334     group_replication
332     perfschema
227     mysqld
212     icui18n
153     libprotoc
131     slave
129     icuuc
123     libprotobuf
97      binlog
65      mysqlgcs
57      mysys_objlib
54      mysql_server_component_services
47      myisam_library


  1. In the case of Postgres, this depends a /lot/ on how you handle dependencies. If you want a specific version of ICU or LLVM, then add that to your compile time. And don't forget extensions - PostGIS isn't exactly a quick compile either...

    That said, did you try the new Meson build system? It seems like a real win! 😀

    1. Fortunately I don't compile many dependencies and from contrib only use pgstattuple.

      Have yet to try Meson. Like many people, I am a jack of all build systems and a master of none. So I am wary about needing to understand another build tool.