Nachdem ich im letzten halben Jahr mit
Neo4j und nun auch mit
Elasticsearch zu tun hatte, bin ich was NoSQL-Datenbanken angeht etwas zwiegespalten. Graphen-Datenbanken sind toll um Beziehungen zwischen Entitäten abzubilden. Dokumenten-orientierte Datenbanken wie Elasticsearch ideal um unstrukturierte Daten zu speichern und neben der eigentlichen Abfrage auch z.B. Durchschnittswerte oder Übersichten von der Abdeckung von bestimmten Attributen/Feldern gleich mit abzufragen.
Die Abfragen sind schnell. Aber.. auch sind die Queries komplexer (Neo4j) bis sehr viel komplexer (Elasticsearch). Der Vorteil der NoSQL Datenbanken ist, dass man schon fertige Objekte zurück bekommt und man nicht auf Tabellenstrukturen beschränkt ist. So kann man also Listen mit Objekten die zu einer Entität gehören gleich mit abfragen und erspart sich ein zweites Query und zusätzliches Mapping.
Aber sind die NoSQL Datenbanken wirklich so viel schneller, wie man immer hört? Dafür muss man verschiedene Dinge bedenken. Zuerst ob die Datenbank die primäre Datenquelle ist oder nur zusätzlich zu einem
RDBMS verwendet wird. Ich hatte bis jetzt nur mit zusätzlichen Datenbanken zu tun. Deren Daten wurden durch Cronjobs aus dem RDBMS gelesen, aufbereitet und dann in die NoSQL-Datenbank geschrieben.
Entweder per
CSV-Import (Neo4J) oder direkt über die REST-API (Elasticsearch). Die gleichen Abfragen waren in der MySQL-Datenbank langsamer. Nicht viel langsamer. Aber es war doch spürbar und lagen bei der Neo4J bei so 30%-40%.
Wenn man nun aber einberechnet wie viel Aufwand der Import darstellt, der bei beiden Anwendungsfällen zwischen 1,5-5min lag, sieht es schon sehr viel anders aus. Die Importscripte reduzierten die Datenmenge natürlich sehr extrem und schrieben nur die nötigsten Daten in die NoSQL-Datenbanken. Bei der Neo4J waren es wirklich nur Ids und Relationen. Die Elasticsearch hatte alle elementaren Felder und auch Unterobjekte, die bei SQL über Joins geladen werden würden. Auf dieser reduzierten und stark vereinfachten Datenbasis waren die Abfragen sehr schnell.
Wenn man mit ein paar SQL-Statements die selben Daten in der MySQL in dem selben Umfang in eigene Tabellen schreibt, ist die MySQL Datenbank meiner Erfahrung nach genau so schnell. Im Vergleich von MySQL und Neo4J muss man sagen, dass für die Abfragen plötzlich viel mehr Daten zur Verfügung stand und diese auf genutzt wurden. Außerdem wurden doppelt so viele Queries verwendet. Am Ende war die MySQL-Lösung langsamer aber auch sehr viel komplexer und in dem Sinne besser.
Ich für meinen Teil sehe in den NoSQL-Datenbank nur einen Vorteil, wenn man die Vorteile derer auch nutzt. Wenn ich keine Graphen brauche, brauche ich auch keine Neo4J-Datenbank. Habe ich nur Entitäten und DTOs die ich schnell speichern und laden möchte, brauche ich keine Elasticsearch. Elasticsearch ist komplex und kann ein paar wirklich interessante Dinge durch deren
Aggregations. Wenn ich haufenweise unterschiedliche Daten aus vielen verschiedenen Quellen zusammen fahren möchte bin ich mit Elasticsearch gut beraten. Aber wenn ich nur Geschwindigkeit haben möchte muss ich nur die Datenbasis verringern und vereinfachen. Neo4J ist auch extrem Speicher hungrig. Was bringt es mir wenn ich 96GB an RAM brauche um das zu machen was ich mit 32GB und einer MySQL oder einer Oracle-DB genau so schnell hinbekomme. Wenn ich dann sehr viel RAM habe und ganze Datenbanken im Speicher halten kann, habe ich die selbe Geschwindigkeit und bin mit der größeren Datenbasis sehr viel flexibler. Außerdem ist alles schneller und sicherer was ich direkt innerhalb der Datenbank machen kann. Ein Import von der MySQL in die Neo4J brauchte viel darum herum um sicher zu sein. In einer Oracle würde alles sowie so in einer Transaction laufen, die auch nicht noch den Server der das Script startet belastet.
Wer also in seinem RDBMS Performanceprobleme hat, soll sie auch dort lösen und nicht glauben, dass ein weiteres System anzubinden (und synchron zu halten) dieses Probleme lösen würde.