Performance Benchmark 2018 – MongoDB, PostgreSQL, OrientDB, Neo4j and ArangoDB
arangodb.com
arangodb.com
Learning all this takes time, you are much better off learning more about your chosen technology stack than switching to another technology stack.
Though in a few rare races, you need a different technology to solve your business problem. In most cases they complement your existing solution, like Elasticsearch/Solr for full-text search or Clickhouse for OLAP workloads.
In most real-world cases the requirements however are not very clear and often conflicting so it's much harder to get data that shows the performance of one system over the other.
And the performance difference could be an accidental feature of the design and completely unintentional.
Postgres for instance has a native data engine, so it can store the exact row-ids for a row into an index, but this means that every update to the row needs all indexes to be updated.
Mysql has many data engines (InnoDB and MyISAM to start with), to the row-id is somewhat opaque, so the index stores the primary key which can be pushed to the data engine scans and then have it lookup a row-id internally. This needs an index to be touched for the columns you modify explicitly or if the primary key is updated (which is a usual no-no due to UNIQUE lookup costs).
When you have a single wide table with a huge number of indexes, where you update a lot of dimensions frequently, the performance difference between these two solutions is architectural.
And if you lookup along an index with few updates, but long running open txns, that is also materially different - one lookup versus two.
Though how it came about isn't really intentional.
https://github.com/weinberger/nosql-tests/blob/master/arango...
Except Neo, which is given a single connection to work with :(
https://github.com/weinberger/nosql-tests/blob/master/neo4j/...
When I modify it locally to just set {maxConnectionPoolSize: 25}, like how the other databases are set up, I get roughly an order better performance. neighbors2 went from 0.0226ms to 0.0068ms, for instance. Single write sync went from 3.36415ms to 0.77549ms avg/op..
Benchmarking is hard!
Did you read the appendix?
"We used a TCP/IP connection pool of up to 25 connections, whenever the driver permitted this. All drivers seem to support this connection pooling, except Neo4j. We sent instead twenty-five requests via NodeJS to Neo4j."
Just to avoid unfair conditions now, if connection pooling is possible with the neojs driver, then you would have to configure the benchmark scripts to not send 25 requests via Node as well.
We tricked ourselves with such stuff when preparing the benchmark.
http://neo4j.com/docs/developer-manual/current/drivers/clien...
A single session object is backed by a single connection, so even though you "send" 25 requests via async.eachLimit, the result is that they are serialized over the single connection.
Thanks again for helping us to improve the benchmark and creating fair conditions for all products tested!
I could see myself there in a bowler hat with a fistful of racing chits screaming “go, Postgres, go.”
I’d love to see a competition were the developers of each database got to use the same hardware and data then tune the hell out of their configs, queries, and indices.
Red Bull could sponsor it. I’d buy a T-shirt.
By the way, there seems to be a raffle of free T-shirts (quite biased, as there's only the ArangoDB logo on them) in exchange for taking part in a survey:
Like esports, for DBAs
On second thought that might be a bad name
You'd want to get some funding to run the tests (or maybe solicit Google or Amazon to see if you could get the instance time donated once a month or something.
If you started small, with maybe a portion of these features, and then scaled up over time, you might actually get to the point where you had tests that emulated a power failure, or master/slave and dual master scenarios and how they handle certain common network errors (split-brain). That would be an amazing resource.
Edit: It occurs to me I probably should have read more of the article, since this is sort of what they are doing already...
It would probably require a few different categories with some sort of output assertion to validate the query performed right and a means of tracking CPU, usage ram usage, and execution time.
It would be cool to see things like disaster recovery and chaos proofing as well.
- 1.6M documents. This is a tiny dataset. I bet it's much smaller than RAM size (122GB), which means all data is in memory. Interesting benchmark, but not what I'd typically expect for a database (data size >> RAM).
- All databases are allowed either to use all memory or capped at 10GB. PostgreSQL is capped at 128MB, the default shared_buffers value on PostgreSQL 10! This means PostgreSQL is running off of disk, whereas the other databases have all data in memory.
- Just to insist on the previous bullet: I see the point (even though I don't consider it interesting, compared to a minimum tuning of every db) of using default config, but this puts PG on a very unfair position (it's limited to 1/1000th of RAM!). Just set shared_buffers to 32GB (or 10GB to cap all db to 10GB!) and re-run the tests. I bet PG results will improve significantly.
- Other basic tuning parameters (like work_mem or min_wal_size or random_page_cost) may also affect significantly the performance. This could be left as an exercise to do another benchmark with properly tuned databases. If interested, here's a recent presentation I did with many other PostgreSQL tuning recommendations: https://speakerdeck.com/ongres/postgresql-configuration-for-...
Other than this, congratulations for the work on ArangoDB. Building a database is a really brave, hard work.
Last week we took a very deep and very wide sales hierarchy query from 10 seconds in Oracle to 4ms in Neo4j. If Arango could it in 3ms, or Orient in 5ms doesn't really matter. The point is graph databases are much better at some queries than relational. They should be blogging about use cases and customer successes, not benchmarks.
They do, just recently the cases of AskBlue (Location aware recommendations) and Thomson Reuters (Fast & Secure Single-View of Everything)
https://www.arangodb.com/why-arangodb/case-studies/
I am very interested in Graph-Cases and appreciate the support of Neo4J for projects like the Panama- or Paradise Papers that show how connected graphs help to understand former hidden relationships. Graphs are very powerful and a great addition to relational or document approaches.
(full disclosure: I worked for ArangoDB 2 years ago.) And, I've used Neo successfully for a fraud detection PoC recently...
But for many people databases have become commodity applications that they install and then forget. So even in reality not all installments will be properly tuned.
I know it happens because I inherit them often. But seriously knock it off.
Errrrr. Better yet don’t, job stability.
Nothing to see here. Move along.
It seems unlikely to me that this group of people would reach benchmark posts.
The result is that the default config is already very good for our benchmark. There is no visible difference between the old and new config when running the benchmark. We will publish an update to the blog post and show the numbers using the tuned config.
best Frank
DBVersion: 10 Linux, Type: "Mixed type of Applications" 122GB RAM 25 Connections SSD Storage
=>
max_connections = 25 shared_buffers = 31232MB effective_cache_size = 93696MB work_mem = 639631kB maintenance_work_mem = 2GB min_wal_size = 1GB max_wal_size = 2GB checkpoint_completion_target = 0.9 wal_buffers = 16MB default_statistics_target = 100 random_page_cost = 1.1
Why? Because nobody who cares about performance runs their database with default configuration. Plus some databases, like PostgreSQL are well known to have very conservative settings. So benchmarking with the defaults like that is knowingly trying to make your product look better than it is. You didn't know? Then what are you doing benchmarking databases?!?
Seriously, this is shady as hell.
You may have to run a utility, or edit a config file, but a new system must be configured to fully utilize available hardware, and for the expected workload.
A benchmark run on default config is at best misleading - it smells like marketing spam. You actually dampen interest in a forum like this with such an approach.
Not really true any more. Many of the newer databases (e.g. Mongo) and database-like systems (e.g. Elasticsearch) try to give a good default experience.
Typically with PostgreSQL, you have to expand the defaults when running on modern server class hardware, so the engine uses enough RAM. Simply letting it use all RAM available can be problematic, since the DB engine and OS have to fight for cache, etc.
Java based systems like Elastic might still need JVM tuning, especially with a distributed platform like ES, which might be run in a large number of small machines, a smaller number of large machines, or containers.
The more common pgtune CLI is not up to date for PostgreSQL 10+ at this time.
Also there are some old, open issues that indicate the benchmarks have problems:
- https://github.com/weinberger/nosql-tests/issues/16 - https://github.com/weinberger/nosql-tests/issues/13
> The shortest path query was not tested for MongoDB or PostgreSQL since those queries would have had to be implemented completely on the client side for those database systems.
I can't speak for Mongo, but I imagine the shortest path query could be implemented as a recursive CTE or a sproc in Postgres, which would execute server side. It might be a bear to write, and it might be slow, but it should be possible.
The largest burden was on development and maintenance. Iterating algorithms and queries powered by RCTEs (and functions) on a changing schema is not scaleable (in effort), at least with the traditional migration scripts approach to upgrades and rollbacks. If you do want go this route, you need to change how you ship those functions and queries.
We theorized that shipping them as part of the application and performing necessary migrations behind-the-scenes would have drastically reduced the maintenance burden. We also considered composing queries completely dynamically and fully leveraging our language (Elixir) to provide a toolbag of functions that aren't functions as far as Postgres was concerned. In either case, the hassle of versioning functions and queries would no longer get in the way iteration.
"I think I've been in the top 5% of my age cohort all my life in understanding the power of incentives, and all my life I've underestimated it. Never a year passes that I don't get some surprise that pushes my limit a little farther." -- Charlie Munger
Unfortunately, there is no independent organization that believes in this and defines scenarios that are tested in different environments.
What's the best strategy here? I've defaulted to MySQL, pg, or sqlite, based on my preference of the moment. I haven't had enough good/bad outcomes to form a stronger opinion, but I'm now realizing I've never really thought this decision through (despite building a few data systems that I'm pretty proud of).
Not sure if still actual, however among headaches I remember race conditions in the node driver(rocksdb engine) and maybe less straightforward clustering (compared to Couchbase/Cassandra/etc at least).
[examples] https://www.arangodb.com/why-arangodb/sql-aql-comparison/
https://news.ycombinator.com/item?id=16378157
[ed: and:
"For comparison, we used three leading single-model database systems:... and PostgreSQL for relational database."
Jsonb with indexes doesn't rate as "document db", how about postgis for domain specific graph db?]
Some agreement on hw (virtual or otherwise), dataset and queries might make this actually rather useful.
You can use the same drivers for PostgreSQL to talk to CockroachDB. As specified here: https://www.cockroachlabs.com/docs/stable/frequently-asked-q...
"CockroachDB supports the PostgreSQL wire protocol, so you can use any available PostgreSQL client drivers."
-- It seems to be highly capable (horizontal-scale/acid) & "performant". Reference vs Neo4j: https://blog.dgraph.io/post/benchmark-neo4j/
Do you maybe have the data for your graphs in csv or json? Want to plot my own graphs with it.
Personally I would call it Javascript Performance Benchmark for MongoDB, PostgreSQL, OrientDB, Neo4j and ArangoDB. Which is mentioned at the end of the article under the software section. To be truly a Database Performance Benchmark you would need to interface with the c/native library.
Can anybody recommend other database benchmarks?
http://snap.stanford.edu/data/com-Orkut.html For an example you can have a look at the import scripts: https://github.com/weinberger/nosql-tests/blob/master/arango...
I wanted to use high-charts to make it interactive, eg hide dbs to compare more easily.
I don't want to run my own tests, but I did have a look at the github repo and dataset.
Please compare apples to apples.
JSONB is also very useful for HTTP JSON APIs because you can have the database construct the JSON response and the API server just returns it. I found it to be faster than constructing the JSON response in the API server most of the time. Of course, it depends on the use case whether you can do that.