Da ich heute mal wieder vor Augen geführt bekommen hab wie wichtig ein Index auf einer Datenbank ist, möchte ich hier meine Erkenntnisse und Erfahrungen mal festhalten.
Zum Kontext, ich habe eine recht simple Anwendung die von einem Kafka Topic Messages konsumiert. Die Message enthält einen Kunden mit Zeiträumen. Der Kunde und die Zeiträume werden in eine DocumentDb geschrieben oder aktualisiert.
Zuerst klingt das alles zu simple um dort einen Fehler zu machen. Leider hatten wir wegen einer Deadline und weil es ein neues Produkt ist, kein guten Lasttest mit vielen Daten.
Deshalb hatten wir jetzt in Produktion das Problem das die Verarbeitungsgeschwindigkeit schon nach 300.000 verarbeiteten Kunden extrem langsam wurden. Und das lag an den fehlenden Indexen. Eine Kunden abfragen über die Kunden Nummer (nicht ID) mit ein Paart Hunderttausenden Kunden braucht allein schon 0.3 Sekunden und die Zeiträume zu der gleichen Kunden Nummer (quasi ein Join) braucht 1.8 Sekunden. Was natürlich die Verarbeitung von Millionen Kunden deutlich verlangsamt. Nachdem wir den Index auf beide Tabellen angelegt haben kamen wir für beide Tabellen auf 0.04 zusammen 0.08 Sekunden, mehr als 25x schneller bei den aktuellen Datenmengen mit gleicher Leistung.
//eine der Querys mit Performance Problemen
db.getCollection("zeitraum").find({ kvnr: "0000000" })
//auch hilfreich
db.getCollection("zeitraum").getIndexes();
//zum erstellen des Index
db.getCollection("zeitraum").createIndex({ "kvnr": 1 }) //, { unique: true }
//Kontrollieren ob der Index auch bei der Folgequery verwendet wird
db.getCollection("zeitraum")
.find({ "kvnr": "0000000", "type": "ANSPRUCH" })
.explain("executionStats").executionStats;
//ergebnis
var ergebnis = {
"executionSuccess": true,
"executionTimeMillis": "0.181",
"planningTimeMillis": "0.121",
"executionStages": {
"stage": "IXSCAN",
"nReturned": "3",
"executionTimeMillisEstimate": "0.040",
"indexName": "kvnr_1", //der erstellte Index
"direction": "forward"
}
}
Wäre eine Relationale Datenbank besser für diese art von Problem gewesen?
Wäre es warum wurde die DocumentDB Normalisiert?
Wäre die Fachliche ID nicht auch gut als Technische Id? Müsste dann überhaupt gesucht werden?
Wie sorgt man dafür das Spring Boot die Indexe automatisch anlegt?