# Optimizing Database Indexes for Performance and Scalability

**Podcast:** Engineering Kiosk
**Published:** 2026-05-26

## Transcript

Willkommen zu einer neuen Episode von deinem Lieblings-Podcast, dem Engineering Kiosk-Podcast.
Heute sprechen wir über Indexstrukturen, also über genau das Thema, das in Datenbank ständig mitläuft, oft super wichtig ist und trotzdem erstaunlich selten wirklich verstanden wird.
Denn ein Index ist eben nicht einfach nur ein Häkchen für schneller.
Dahinter stecken Datenstrukturen, Algorithmen, Hardware, Zugriffsmuster und eine ganze Menge Trade-offs.
Wir schauen uns an.
Was ein Index eigentlich ist, warum ein Full-Table-Scan manchmal trotzdem sinnvoller sein kann, was Selektivität und Kardinalität mit deiner Query-Performance zu tun haben und warum ein falscher Index nicht nur nichts bringt, sondern sogar schaden kann.
Außerdem sprechen wir über Read-Heavy und Write-Heavy Workloads, über Write-Amplification, Observability, Slow-Query-Logs und darüber, wie der Optimizer in Datenbanken überhaupt entscheidet, ob ein Index verwendet wird oder halt auch nicht.
Und danach wird es halt noch ein bisschen praktischer.
Wir sprechen über Hauptspeicher versus Sekundärspeicher, B- und Binärbäume und über unsichtbare Indizes in MySQL.
Ja, richtig gehört, unsichtbare Indizes.
Klingt irgendwie schräg, ist aber doch schon ziemlich nützlich.
Wenn du also verstehen willst, warum Datenbank-Performance nicht mit Create Index erledigt ist, dann bleib dran.
Die Episode ist für dich.
Los geht's.
Der Engineering Kiosk ist ja nicht nur ein Podcast.
Der Engineering Kiosk ist inzwischen eine ganze Entwickler-Community mit echt über 500 Leuten im Discord.
Und wir haben sogar zwei Meetups.
Eins in Innsbruck, das macht der Wolfgang mit einem ganzen Team schon seit einer längeren Zeit.
Und in Rhein-Ruhr, in Deutschland, in der Rhein-Ruhr-Region haben wir jetzt auch ein Meetup.
Und das hatten wir die Tage.
Und dann hat der Shep, grüße gehen raus, auch so ein kleines Intro gemacht.
Okay, was ist der Engineering Kiosk?
Und hat dann unter anderem auch das Bild des Podcasts gezeigt und sagte, ja, wer irgendwie so auf Backend-Infrastruktur steht, der sollte in diesen Podcast mal reinhören.
Und hat danach auch seinen Podcast vorgestellt, den Working Graph Podcast, grüße gehen auch da raus.
Und hat gesagt, wer mehr auf Frontend steht.
So, Wolfgang, Infrastruktur und Backend-Podcast.
Siehst du das auch so?
Und was hast du zu deiner Verteidigung zu sagen?
Also ich bin schnell mal auf unsere Webseite gegangen und habe auf den Tag Kommunikation geklickt.
Und da sind, glaube ich, über 30 Episoden, wo es nur ums Thema Kommunikation geht.
Jahresgespräch, Performance Reviews, Imposter-Syndrom, Datenjournalismus.
Also das stimmt schon.
Wir kommen wahrscheinlich sehr aus der Backend-Welt, aber wir machen schon sehr viel.
Und das ist ja auch das Credo von diesem Podcast, dass wir auch andere Sachen machen rund.
über den Tellerrand, Rundumschlag in der IT-Szene.
Und da wir ja da so viel machen, ist es jetzt eigentlich schon wieder Zeit für eine ordentliche Backhand-Folge.
Ich habe dieses Intro nicht einfach so gewählt, denn jetzt befeuern wir die ganze Thematik mal wieder.
Denn für die Leute, die es nicht wussten, der Wolfgang hat einen Doktortitel im Bereich Datenbanken.
Und wir wären ja schön doof.
wenn wir das nicht auch mal ausschlachten würden.
Im Produktivitätsbereich würde man sagen, wir nutzen mal ein paar Synergien, denn solche Themen fallen dem Wolfgang natürlich immer ganz locker von der Hand.
Und deswegen beschäftigen wir uns heute mal, mal oder mal wieder, das weiß ich gerade gar nicht mehr, über Indexstrukturen.
Indexstrukturen kommen bei den meisten Leuten im Kopf immer nur in Datenbanken vor.
Es wird aber nicht nur in Datenbanken angewendet.
In sehr vielen Compute-lastigen Applikationen gibt es ebenfalls Indexstrukturen.
Deswegen, Wolfgang, Indexstrukturen, was hast du dazu zu sagen?
Also nur um das gerade oder glatt zu ziehen, wie du ja immer so schön sagst, war gerade am Tag Datenbanken bei uns auf der Webseite, da haben wir ungefähr 20 Episoden.
Also wir haben mehr Kommunikationsepisoden als Datenbank-Episoden auf jeden Fall.
Und wir hatten schon mal über Indexstrukturen gesprochen in einem sehr speziellen Bereich, Geo-Indexstrukturen, also räumliche Indexstrukturen.
Wir hatten auch mal eine Episode, wo es um Gaming-Indexstrukturen sogar gegangen ist, also sehr spezialisierte Episoden.
Aber wir hatten bisher eigentlich noch nie so eine grundlegende Episode, wo wir mal besprechen, was es eigentlich für Indexstrukturen im Allgemeinen gibt, was Fort- und Nachteile sind, Hauptspeicher, Sekundärspeicher, also Festplatte.
Woher kommt das Ganze?
Und genau darum soll es in dieser Episode mal gehen.
Wie sagt man bei uns so auf dem Dorf, dann lass uns nicht lang schnacken, Kopf in den Nacken.
Gilt eigentlich für Saufen.
Deswegen übertragen wir das jetzt mal auf das Thema.
Hauen wir direkt raus.
Was ist eigentlich ein Index?
Also wahrscheinlich haben wir alle von einem Index schon mal gehört in der Schule oder wenn sie damals irgendwie so ein Lexikon, also ich hoffe, sind alle so alt, dass sie ein Lexikon kennen, also so ein Buch, wo man hinten so ein Index drin hat.
Der hat schon Index geheißen.
Das ist so die Grundform, aber wir in der Tech.
Szene verstehen natürlich was anderes unter dem Index und ich würde mal grundsätzlich das eigentlich so definieren, dass ein Index eine gewisse Struktur beziehungsweise sogar ein Vertrag ist, wo man versucht, eine gewisse Datenstruktur zu implementieren, die dann einen Optimierer oder Algorithmus hat, um mit dieser Datenstruktur zusammenzuarbeiten und das Ganze immer spezialisiert auf eine gewisse Hardware.
Also die Hardware spielt da auch immer eine Rolle, wo wird das Ganze ausgeführt.
Auf einer Festplatte, im Hauptspeicher, habe ich eine SSD-Platte, habe ich einen schnellen RAM, habe ich Caches, L1-Cache, L2, L3.
Und wie ist der Workload?
Also wie greife ich auf diese Daten zu?
Und meistens wird das Ganze ja optimiert für einen speziellen Workload.
Also Facebook hat wahrscheinlich einen anderen Workload als Wikipedia.
Weil Wikipedia hat ganz viele Read-Zugriffe.
Facebook hat wahrscheinlich auch ganz viele Schreibzugriffe.
eine andere Plattform, wo es um Chats zum Beispiel geht, wo man einfach viele, viele Writes eben auch hat oder Änderungen in dem Sinne.
Und genau dafür optimiert man dann diese Datenstruktur, diesen Algorithmus, damit das Ganze dann am Ende schneller funktioniert.
Und die Grundannahme ist eigentlich immer, ich probiere eigentlich meine Rechenzeit runter zu bekommen, indem ich weniger Daten anfassen muss oder wie in Österreich, sag mal, angreifen.
Da bist du ja immer verwirrt, wenn man Daten angreifen sagt oder dich angreifen.
Das ist schon nochmal ein Unterschied.
Auf jeden Fall, man will möglichst wenig Daten anfassen, berühren in irgendeiner Form, weil es ist meistens langsam.
Und wenn ich natürlich jetzt 100 GB an Daten habe, aber für irgendeine Anfrage nur 10 MB berühren muss oder irgendwie laden muss, bin ich am Ende schneller.
Und das ist eigentlich so das Ziel von einem Index.
Egal, ob das im Hauptspeicher ist, auf der Festplatte, auf einem Bandlaufwerk, soll es ja auch noch geben, kann man eigentlich überall abbilden.
Hast du gerade geglaubt, irgendwas ist kaputt?
Ja.
Siehst du, so geht es mir auch oft.
Und dann brauche ich unbedingt einen Kaffee.
Oder wie der Andi sagen würde, einen Kaffee.
Und für diese Koffeinenergie Die ihr uns durch diese Kaffeespenden bereitstellt und die es uns eigentlich erst ermöglichen, diese Episoden zu produzieren, möchten wir uns einmal bedanken.
Und zwar bei den letzten Spendern.
Daniel, Jakob, Peter, Alfred, Florian, Michel, Dimo, David, Lukas, Adrian, Nico, Matthias, Wolfgang, by the way, schöner Name, Elias, Björn, Franco, Dominik, Paul und Fabian.
Und egal, ob ihr uns einen Kaffee sponsert oder vielleicht sogar ein Kaffee-Abo wie der Fabian oder einen ganzen Monatsbedarf an Kaffee wie der David, wir schätzen jeden einzelnen Kaffee und freuen uns wirklich über dieses ganze Koffein-Feedback.
Vielen Dank von Andi und von mir und jetzt geht es auch schon wieder zurück zur Episode.
Wenn wir nochmal über die Verbindung zu der Hardware sprechen, dann sprechen wir nicht über Hardware-Generationen wie zum Beispiel CPU.
ob das jetzt in x86 oder ARM ist, sondern wir sprechen eigentlich darum, okay, CPU-lastig, RAM-lastig, Disk-lastig und nicht, ob die CPU eine 2-Gigahertz-Taktung oder eine 3-Gigahertz-Taktung hat.
Bei Disks mag es vielleicht ein bisschen anders sein.
Bei SSDs versus Spinning-Discs, da ist es vielleicht ein bisschen anders, wegen der Aufteilung, wie die Daten auf die Platte geschrieben werden.
Da hatten wir ja, glaube ich, da hatten wir ja auch mal eine Episode über OLAP versus OLTP und auch über Versus Spaltenorientierte Datenbanken, wo das Disk-Layout ja dann auch eine Rolle spielt.
Aber wenn wir uns jetzt mal von der Festplatte entkoppeln, dann sprechen wir jetzt nicht über die Taktung von RAM oder die Taktung von CPUs, sondern eher über CPU und Cache-Größen versus RAM versus Disk generell.
Und da über die Unterschiede in der Geschwindigkeit, also über die sogenannte Order of Magnitude.
Also wenn du jetzt...
alle Index-Struktur-EntwicklerInnen beleidigen willst, dann kann man davon ausgehen, ja.
Aber die ganzen Leute, die sich die letzten 15 Jahre damit beschäftigt haben, die optimieren natürlich auf alles.
Und alleine diese ganze Änderung in letzter Zeit, dass die L1 bis L3-Caches größer geworden sind oder wie die CPU kommuniziert, wie gelockt wird, was in einem gesherten Cache auf der CPU passiert oder nicht passiert oder was.
geshared werden kann zwischen Kerne.
Das spielt natürlich alles eine Riesenrolle.
Also die reinen Taktfrequenzen spielen jetzt vielleicht weniger die Rolle, aber alles andere, was an Architektur irgendwie möglich ist, Instruction Sets, ob du auf der CPU irgendwas parallel abarbeiten kannst, SIMD, das spielt natürlich alles in die Indexstrukturen rein und wenn du auf die großen Datenbankkonferenzen blickst, so wie eine FileDB, Very Large Database ist, ist eine der größten.
Da findest du überall Papers, die da die letzten Prozent irgendwie nochmal rausholen, um für eine ganz spezielle Architektur nochmal irgendwie in einer Indexstruktur mit einem Delta vom Delta vom Delta, also der 18.
Verbesserung von einer Indexstruktur nochmal irgendwo ein bisschen rausholen.
Und gerade die großen Companies wie Meta oder Google, bei denen bringt natürlich dieses 0,005% auch noch was natürlich bei ihren Indexstrukturen.
Und wenn du von workload-spezifischen Strukturen sprichst, dann kommt mir immer eine Sache in den Sinn, die ich in meiner Karriere super oft hatte und die vielleicht auch jeder hier schon kennt.
Der klassische Satz, das skaliert nicht.
Denn wenn ich eine Sache in meiner Karriere gelernt habe, dann ist das immer, wenn ich höre, das skaliert nicht, dann hat die Person wahrscheinlich am Vorabend Hacker News gelesen und da kam irgendeine neue Datenbank hoch, die man dann in die Produktion schippen möchte.
Oder...
Die Person hat den Satz einfach sehr schnell gesagt, weil es sehr einfach ist, diesen Satz zu sagen, um dann ein sehr spannendes Projekt zu launchen.
Ich habe aber auch gelernt, und jetzt kommt die positive Seite, dass immer wenn man sagt, das skaliert nicht, dass es sehr viel Optimierungspotenzial in diesen Workloads gibt.
Das bedeutet, haben wir als Engineering Team eigentlich verstanden, welche Daten, welche Tabellen wir in welchem Volumen schreiben versus lesen.
Also haben wir einen Write-Heavy-Workload oder einen Read-Heavy-Workload?
Haben wir einen Traffic-Serving-Workload oder haben wir einen Batch-Workload, der vielleicht nicht so zeitintensiv ist, wo es keine Rolle spielt, ob das jetzt 5 oder 15 Sekunden lang dauert, wohingegen bei einem Traffic-Serving-Workload, also einem Live-Traffic, sei es Mobile-App, sei es irgendwas anderes, auf Millisekunden ankommt.
Also du hast jetzt gerade OLTP und OLAP nochmal erklärt.
Also OLAP ist Analytik, da hat man Zeit.
OLTP ist Transactional, da hat man wenig Zeit.
Aber genau das ist eben der Punkt.
Du hast im Prinzip diese vier Punkte, Datenstruktur, Algorithmus, Hardware und Workload und diese vier Sachen müssen zusammenpassen.
Wenn man das jetzt ganz unten mal...
aufmachen, diese vier Punkte bei dem Index in der Volksschule, aber wie heißt das bei euch?
Grundschule.
In einem Lexikon, wenn man das mal sieht, in einem Lexikon habe ich einen Workload, wo ich mir denke, okay, in einem Lexikon will ich vielleicht gewisse Begriffe oder allgemein in einem Buch will ich gewisse Begriffe schnell nachschauen können, dass ich schnell die Seitenzahl finde.
Es ist rein Read-driven, würde ich mal sagen.
Dann habe ich eine Hardware, das ist mein Buch, meine Seiten in dem Fall.
Das sind einfach klassische Seiten, die ich umblättern kann, ist im Speicher aber eigentlich eh sehr ähnlich, wenn man sich das anschaut.
Dann habe ich eine Datenstruktur.
Ich habe einfach eine lange Liste, aber in dem Fall habe ich eine sodierte Liste üblicherweise in dem Index hinten im Buch.
Das heißt, es ist schon mal sodiert.
Ich habe da irgendeine Struktur drinnen, eine sodierte Liste.
Das wäre die Datenstruktur.
Und dann habe ich den Optimizer oder den Algorithmus, der da drauf läuft.
Der läuft natürlich bei uns im Gehirn bei einem klassischen Buch.
Übrigens, Buch muss ich dir nicht erklären, Andi.
Kennst du noch, oder?
Kenn ich sogar sehr gut.
Ich habe ein Hobby.
Ich kaufe Bücher.
Das heißt nicht, ich lese sie, sondern ich kaufe sie.
Also ich habe hier einen großen Stapel links und rechts vor mir von Fachbüchern, die ich alle sehr gut finde und alle lesen möchte.
Doch naja, gut, das ist halt schwierig.
Du kannst ja mal den Index hinten anschauen.
Vielleicht kannst du dann schon ein paar Inhalte rausziehen.
Auf jeden Fall hat man dann die studierte Liste und der Algorithmus läuft dann im Kopf ab.
Und das ist üblicherweise die Binary Search, die wir im Kopf anwerfen, mehr oder weniger.
Das heißt, wenn wir wissen, wir suchen nach irgendetwas, was mit K anfängt, keine Ahnung, Konflikt zum Beispiel als Wort, dann schauen wir natürlich schon, wo sind die Wörter mit K und dann machen wir so eine binäre Suche, um das möglichst schnell einzugrenzen.
Wir schauen mal bei alle Ks, wo sind die nächsten Buchstaben?
Ist das eher vorne in den K-Listen oder eher hinten?
Und so macht man dann ein paar Checks und probiert sich anzunähern, ganz klassisch wie in einer binären Suche.
um das zu finden.
Also eigentlich haben wir das im echten Leben genauso, diese Indexe und Indexierungen und ein Algorithmus im Kopf und das Ganze kann man eigentlich wirklich eins zu eins umsetzen dann auf die Technik und auch da wieder, egal ob im Hauptspeicher oder Festplatte oder wo wir auch immer umgehen oder bei uns in der Software, wenn wir es programmieren, ist eigentlich immer dasselbe.
Wir wollen schnell...
auf Daten zugreifen können und Sachen schneller finden, ohne dass wir eben das ganze Lexikon durchsuchen oder den ganzen Index durchsuchen.
Und dieses Vorgehen wird dann optimiert.
Und das fällt eigentlich alles in Indexstrukturen.
Also man kann nicht nur, wie du richtig sagst, das nur auf einen Index an sich reduzieren.
Man muss immer alles rundherum wissen, um das dann am Ende optimieren zu können.
Und wenn man den falschen Index verwendet für den Workload, dann ist das Ganze natürlich Langsam und dann kommt das, es skaliert ja nicht, aber vielleicht hat man einfach den falschen Index gewählt oder hat gar keinen Index gewählt oder hat sich einfach gar nicht beschäftigt damit, wie man die Daten vielleicht ablegen kann in einer besseren Datenstruktur, um dann am Ende schneller zu sein.
In der Episode 265, wo wir über die One Billion Road Challenge gesprochen haben, haben wir auch über die Kritik von Dataset Overfitting gesprochen.
Das bedeutet, man optimiert seinen Algorithmus ganz genau auf die Daten, die man da hat.
Wenn ich das jetzt auf...
Das um Münze, was du jetzt gerade gesagt hast, dann ist ja Dataset-Overfitting in Bezug auf Index-Design sehr vorteilhaft, oder?
Solange du garantieren kannst, dass dein Dataset gleich bleibt.
Das ist eigentlich das größte Problem in der Datenbankwelt oder ganz allgemein natürlich.
Du baust jetzt irgendeinen Index für einen ganz speziellen Use-Case.
Das heißt, du machst eine Datenstruktur, einen Algorithmus drauf, kennst dir deine Hardware ganz gut und kennst auch den Workload.
Du hast so und so viele Zugriffe, zum Beispiel 1000 User.
Du musst die Daten speichern von 1000 User, alles kein Problem, funktioniert schnell.
Und über die Zeit kommen jetzt plötzlich ganz viele User dazu oder du hast einen coolen Marketing-Effekt und hast plötzlich 10.000 User.
Plötzlich ändert sich dein Workload oder deine Daten ändern sich, weil plötzlich so viel geschrieben wird.
Und dann stimmen diese Annahmen alle nicht mehr.
Das heißt, es kann natürlich über die Zeit passieren, dass diese Index-Strukturen nicht mehr geeignet sind oder nicht mehr die richtigen sind.
Und das macht ja bei so einem lebenden System eigentlich das Problem aus.
Und darum hat man ja früher auch diese DBAs, die Datenbankadministratoren gehabt, die sich immer das angeschaut haben, funktionieren unsere Datenbanken noch, ist alles noch schnell.
Mir hat gerade ein Freund erzählt, der ist ein Datenbankadministrator für MS SQL.
Die haben einfach ein Update eingespielt und plötzlich war alles langsam bei denen.
Und sie haben wirklich...
eigentlich nie an dieses Update gedacht, weil es auch ein bisschen verzögert war und so weiter.
Also das klassische Problem, erst ein paar Tage später.
Und am Ende sind sie aber draufgekommen, ja, das Update hat halt irgendwas in den Algorithmen geändert und plötzlich war alles langsam bei denen.
Das bringt mich aber zu der nächsten Frage.
Man kennt ja das gute Strichwort, wenn ich mit der Zeit gehe, geht mit der Zeit.
Und somit ist ja ein...
Das Strichwort.
Das Strichwort sozusagen, ja.
Man wird dann auch gestrichen, das ist richtig.
Pun intended oder beziehungsweise nicht intended.
Wenn du nun sagst...
Wenn du einen Index einführst, hast du gewisse Annahmen an die Daten.
Und diese Annahmen müssen weiterhin stimmen, damit der Index auch seinen Soll erfüllt.
Jetzt wird aber jede Applikation kontinuierlich geändert.
Und die seltensten Datensätze sind statisch.
Und wenn sie statisch sind, überlege ich gerade, braucht man dann eigentlich einen Index oder kann man da nicht ziemlich viel precomputen?
Das ist eine andere Thematik.
Naja, ein Index ist ja nichts anderes als precomputed eigentlich.
Also klar wird der verändert, aber eigentlich, wenn du...
ein statisches Datenset hast und einen Index machst, dann precomputest du eine andere Sicht auf die Daten und das ist genau so ein Index.
Ich glaube, meine Frage ist eigentlich, was sind denn Best Practices, um deinen Index kontinuierlich zu kontrollieren, ob die initialen Annahmen in Relation zu den Daten eigentlich noch stimmen?
Also eigentlich ist das ja so eine Art, wenn ich das im Infrastrukturbereich vergleiche, eine Art Capacity Planning für deine Daten.
Nicht für Server, nicht für Speicherplatz, nicht für RAM.
sondern für deine Daten.
Gibt es da Best Practices, die du aus dem Hut zaubern kannst?
Und ich meine jetzt nicht higher einfach eine Armee von Datenbank-Administratoren?
Ja, grundsätzlich gelten die gleichen Regeln, wie du jetzt gesagt hast, aus dem Infrastrukturbereich.
Du brauchst mal Observability und die hast du üblicherweise ja schon mal ganz, ganz oben auf der Application-Seite.
Und wenn dort was langsam wird, dann musst du rausfinden, liegt es an der Datenbank.
Das Ganze gibt es natürlich auch auf der Datenbankseite.
Du kannst die Datenbank monitoren.
Du kannst herausfinden, welche Queries dauern lang.
Alle, die in der MySQL-Welt unterwegs waren, Slow Query Lock ist so das Schlagwort schlechthin.
Aber du kannst es natürlich grundsätzlich nicht verhindern.
Du kannst es probieren, vorherzusehen und so grob einschätzen, okay, was wird sein, wenn du viele Daten...
Plötzlich reinbekommen, funktioniert das noch gut, aber im Endeffekt musst du es monitoren und dann eben auch dementsprechend agieren.
Die Datenbanken sind natürlich schon einigermaßen schlau und die halten mittlerweile Statistiken und probieren auch für den internen Optimizer den richtigen Index rauszusuchen.
Also da gibt es natürlich schon viele Punkte, die die Datenbank versucht automatisch zu machen und mittlerweile immer mehr automatisch zu machen und intelligent zu machen.
Aber grundsätzlich ist die Datenbank so wie...
die Codebase an sich auch in irgendeiner Form lebendes System und kann über die Zeit degraden und langsamer werden und wird sie üblicherweise auch, weil du ja tendenziell immer mehr Daten bekommst.
Über diesen Aspekt habe ich eigentlich so noch nie nachgedacht.
Es gibt Firmen, die stellen Performance Engineers ein.
Zum Beispiel auf dem letzten Rhein-Ruhr-Engineering-Kiosk-Meetup war jemand, der hat mal bei Komoot gearbeitet und hat da die Frontend-Performance optimiert.
Und was sie gemacht haben, die haben bei jedem Pull-Request Frontend-Tests laufen lassen, um zu gucken, ob die Frontend-Performance degraded wird durch den Pull-Request, was ja sein kann.
Ich habe sowas eigentlich noch nie für Datenbank-Indizes gesehen.
Die Datenbank-Hersteller haben sowas, also die haben riesige Test-Sets von Kunden auch, weil die wollen ja üblicherweise nicht ihre Kunden langsamer machen, außer es ist MS SQL und bei meinem Kollegen, der wirklich in dem Fall alles dann langsamer hatte, aber genau das wirst du eigentlich verhindern.
Du hast riesige Test-Sets, die dann durchlaufen.
über Tage meistens, um zu checken, hat irgendein Update eine Auswirkung auf irgendeinen speziellen Data Load und Workload.
Meistens, wie gesagt, große Kunden haben dann auch eigene Test Sets und die laufen dann wirklich tagelang durch und checken, gibt es irgendwo Probleme oder können wir das neue Release wirklich rausbringen und ausrollen.
Und das kannst du natürlich auf deiner Seite als Programmierer ihn natürlich genauso machen und haben.
Und manche Leute haben das natürlich auch, dass die in den Tests gewisse Workloads abarbeiten, um das dann wirklich zu testen.
Und wenn du das Wort Workloads wieder in den Mund nimmst, fällt mir noch eine Frage ein.
Würdest du sagen, ein Lexikon ist eher ein Read-heavy Workload und kein Write-heavy Workload?
Weil du hast ja vorhin den Index anhand eines Lexikons beschrieben.
Genau, habe ich glaube eh gesagt, das ist klassisch Read-heavy natürlich, weil eigentlich nur gelesen wird.
Und das Schreiben passiert halt einmal beim Druck eigentlich.
Wobei natürlich das Lexikon an sich ganz praktisch ist, weil da kommt halt nichts dazu.
Das heißt, ich brauche den Index nicht updaten.
In der Datenbank oder im Hauptspeicher habe ich natürlich das Problem, dass ich ständig neue Daten reinbekomme und immer den Index auch updaten muss.
Und diese Write-Amplification, wenn ich ganz viele Indizes, mit updaten muss.
Das heißt, ich schreibe eigentlich nur eine Zeile, muss aber an 20 verschiedenen anderen Stellen den Index updaten.
Das heißt, das nennt sich dann Write Amplification, weil ich eben statt einem Write dann am Ende 20 machen muss.
Dann wird halt alles langsam.
Also dieses Updaten der Indizes braucht natürlich auch Zeit und wenn es dann um Transaktionen geht und das mit reinfließt womöglich, dann wird eben alles dementsprechend langsamer, muss man natürlich auch immer mit beachten.
Also umso mehr parallele Datenstrukturen ich halte, umso mehr muss ich auch updaten.
Die Write Amplification ist also eigentlich das, was so ein Fanout von Microservice-Requests macht, wenn du einen Microservice anfragst und der 20 Fanout macht, also eine Request-Verstärkung, wenn du so möchtest, und hier eine Schreib-Verstärkung, dass du dir selbst gegebenenfalls ins Knie schießt.
Genau.
Okay, Basis geklärt, finde ich super.
Kommen wir zum zweiten Basis-Thema.
Gib mir nochmal einen Rundown über die Kernkonzepte von Datenbanken.
Also, ich habe eine Tabelle, nehmen wir mal...
Kundendaten oder User, ganz klassisch.
Ich habe einen Primary Key, eine E-Mail, ein Land und vielleicht wann der Record angelegt wurde.
Da fängt es sich schon mal an.
Primary Key.
Key ist eigentlich in der Datenbankwelt immer ein Vote-4-Index.
Das heißt, du hast mit dem Primary Key eigentlich schon einen Index auf deinen Daten drauf.
Und üblicherweise ist der Primary Key, darum heißt der Primary Key, der Key, der bestimmt, wie die Daten sortiert sind.
Das heißt, üblicherweise sind die Daten nach dem Primary Key sortiert.
physikalisch wirklich auf der Festplatte im Speicher.
Und wenn du jetzt nach irgendwas suchst, also wenn du deine User hast, Select-Stand-From-User-Ware-E-Mail-ist-Andi-at-Engineering-Kiosk.dev, da müsstest du durch deine ganzen User durchgehen und überall schauen, ist die E-Mail-Adresse irgendwo vorhanden.
Das heißt, du machst einen Full-Table-Scan.
Das heißt, du gehst durch alle Daten durch, lädst alle Daten durch die gesamte Speicher-Pipeline, das heißt von der klassischen Festplatte, egal ob SSD oder sonst was, in den RAM, in den L1-Cache.
Na, umgekehrt.
L3-Cache kommt zuerst, L2 und dann L1.
Dann die Register und dann kommt der eigentliche Vergleich.
Ist es wirklich diese E-Mail-Adresse?
Wir hatten auch kürzlich in der Episode von der One Billion Row Challenge, diese String-Vergleiche sind sehr teuer.
Strings sind sehr lang, müssen alle nochmal durchgepiped werden und das wäre natürlich super langsam.
Sogar bei kleinen Tabellen kann es unter Umständen schon sehr langsam sein.
Und da würde sich natürlich ein Index anbieten, wenn ich oft diese E-Mail-Adresse suche.
baue einen eigenen Index auf, in diesem Index steht die E-Mail-Adresse von den einzelnen Usern und dann steht irgendwo andy.engineeringkiosk.dev ist die ID 18 und dann suche in diesem sortierten Index, der nach der E-Mail-Adresse sortiert ist, bin ich sehr schnell, Andi, könnt ihr zum Beispiel eine binäre Suche machen in meinem Index, finde Andi sehr schnell, weiß dann, das ist die ID 18 und dann hole ich mir die eigentlichen Daten aus der User-Tabelle.
mit der ID 18 vom Andi und habe nur einen Zugriff auf der Festplatte.
Im Idealfall passt der Index vielleicht sogar in meinen Hauptspeicher.
Das heißt, ich kann im Hauptspeicher super schnell nach Andi suchen, nach der E-Mail-Adresse.
Und wenn ich seine Adresse brauche, mache ich dann eine Punktanfrage und hole mir genau die Adresse von der Festplatte, von der SSD, wo der Andi gespeichert ist.
Testfrage, Computer Science 101, was ist eine binäre Suche?
Wie funktioniert die?
Du hast das gerade so salopp gesagt, als müsste das jetzt hier jeder ohne AI locker programmieren können.
Ich habe es eh schon erwähnt mit dem Lexikon und eigentlich machen wir da mehr oder weniger eine binäre Suche.
Wenn du eine lange Liste hast, die sortiert ist, dann fängst du üblicherweise mal in der Mitte an, checkst in der Mitte, was für einen Buchstaben hast du in der Mitte und dann entscheidest du, musst du weiter vorne nachschauen oder weiter hinten.
Das heißt, wenn ich nach Andi suche, A kommt üblicherweise am Anfang, könnt ihr in dem Fall schon wissen, aber wenn ich die klassische binäre Suche mache, schaue genau in der Mitte, wo lande ich da, wenn ich da jetzt zum Beispiel M habe in der Mitte, dann weiß ich, okay, ich muss nach links gehen, nehme dort wieder die Mitte, komme irgendwo bei K an, weiß ich, okay, ich muss wieder nach oben gehen Richtung A, nehme wieder die Mitte und so suche ich mir immer wieder die Mitte heraus und prüfe so lang die Mitte und entscheide, muss ich links oder rechts gehen, bis ich an die gefunden habe.
Und das nennt sich binäre Suche, weil sich der Suchraum immer halbiert.
Das heißt, ich mache die erste Hälfte.
dann in der linken Hälfte halbiere ich wieder.
Also es wird immer halbiert, der Suchraum.
Und darum komme ich dann relativ schnell, weil es logarithmisch ist, zu meinem eigentlichen Ziel.
Und das ist ganz allgemein.
Üblicherweise bei Baumstrukturen hat man immer logarithmischen Zugriff.
Wir haben ja schon mal eine Episode zur O-Notation gehabt.
Also wie komplex ist so ein Algorithmus?
Wie schnell komme ich ans Ziel?
Wie viele Daten muss ich verarbeiten?
Und Indexstrukturen sind üblicherweise Bäume.
Und Bäume sind immer logarithmisch.
Okay, ich suche jetzt eine E-Mail.
habe die E-Mail in meinem Index gefunden, habe dann die ID der Zeile gefunden und lese dann die ganze Zeile.
Okay.
Dabei kommt die Frage auf, gibt es denn auch Situationen, wo ein Index langsamer sein kann als ein kompletter sequenzieller Table Scan?
Das gibt es nicht nur, sondern das kommt sogar sehr oft vor.
Und das ist ein Grundsatzproblem, wenn man immer sagt, okay, irgendwas ist langsam, ich werfe mir einen Index drauf.
Weil da sind wir genau wieder bei dem Punkt, ich muss wissen, was macht der Index, was für einen Workload habe ich und wie funktioniert das eigentlich im Hintergrund.
Und wenn man sich das anschaut, dann muss man so ein bisschen verstehen, wie Indizes eigentlich funktionieren.
Und zwar, wie das ja schon erwähnt, wenn wir jetzt einen Index haben auf die E-Mail-Adressen, dann ist dieser Index nichts anderes als ein Nachschlagewerk, wo eigentlich die einzelnen User gespeichert sind.
Also ich habe die E-Mail-Adresse, sortiert nach der E-Mail-Adresse und dann steht da ID 18.
Jetzt muss ich aber einen Sprung auf die ID 18 machen.
Dieser Sprung, der kostet mich natürlich auch was.
Das heißt, ich suche jetzt alle E-Mails durch, finde die E-Mail-Adresse, finde die ID und mache dann einen Sprung auf die Festplatte.
Und dieser Sprung kostet mich Zeit, CPU-Cycles und so weiter.
Wenn ich jetzt annehme, die Tabelle hat sowieso nur 100 Einträge und die könnte sequenziell durchgehen.
und habe die im Hauptspeicher, dann kann das schneller sein, als ich mache einen extra Index, der auch abgedatet werden muss.
Ich muss in dem Index nachschlagen, ich muss dann springen auf die Festplatte, muss mir die Daten holen.
Also dieser gesamte Ablauf von dem Index, von dem Lookup, kann unter Umständen langsamer sein.
Also das kann eigentlich immer sein, wenn die Daten klein sind.
Ein anderer Punkt, der in der Datenbankwelt sehr wichtig ist, ist die Selektivität von einem Index.
Das heißt, wie selektiv ist er?
Die E-Mail-Adresse ist natürlich super selektiv, weil üblicherweise ist die sogar unique in meinem Dataset, das heißt, die gibt es nur einmal, das heißt, ich habe einen Treffer.
Wenn ich jetzt aber einen Index habe über zum Beispiel das Land, woher meine User kommen, also das wir im Land, und die machen einen eigenen Index und bin jetzt aber im deutschsprachigen Raum unterwegs, dann werden 90% meiner User DE als Land haben.
Wenn ich da jetzt einen Lookup mache in meinem Index und der Index hat nur die Länderinformationen, dann bekomme ich natürlich von meinem Index 90% aller IDs zurück und muss dann erst wieder auf die Tabelle.
Das heißt, mir bringt dieser Index überhaupt nichts.
Der ist absolut sinnlos.
Das heißt, die Selektivität, also wie sehr filtert mein Index die Daten eigentlich, auf diese Selektivität muss ich auch wirklich achten und nur eine hohe Selektivität macht eigentlich Sinn.
Also niedrige Selektivität, wenn meine Daten nicht ordentlich eingeschränkt werden, sobald ich den Index verwende.
gibt es ein Problem.
Und da kommt der Optimizer auch ins Spiel wieder von den Datenbanken, weil der schaut sich natürlich an, wie selektiv ist ein Index, verwende ich diesen überhaupt?
Und eine schlaue Datenbank sagt dann, nope, hat eine niedrige Selektivität, ich gehe sofort auf die Daten und mache einen Full Table Scan, weil das dementsprechend noch schneller ist.
Du hast einen interessanten Punkt angesprochen, weil da sind wir ja schon wieder hier, kenne deine Daten, weil in deinem Beispiel gab es 80 oder 90 Prozent Deutsche, aber was ist denn, wenn ich jetzt nach Österreich filtern würde?
Dann hätte ich ja...
nur noch 10 oder 15 Prozent oder 20 Prozent der Records und dann hätte ich ja wieder eine hohe Selektivität, oder?
Genau, die Selektivität hängt natürlich auch von der Query grundsätzlich ab, beziehungsweise die Verteilung in diesem Index oder Kardinalität, also wie viele unterschiedliche Werte habe ich denn da überhaupt drinnen?
Jetzt bei den Ländern hätte ich wahrscheinlich nur im Dachraum jetzt drei Werte, Deutschland, Österreich, die Schweiz.
Und die Verteilung ist wahrscheinlich ziemlich ungleichmäßig oder skewed auf Englisch, weil ich natürlich sehr viel Deutsche in meinem Index habe.
Das ist die Frage, macht jetzt der Index natürlich trotzdem Sinn, wenn ich zum Beispiel nach österreichische Personen suche, dann habe ich vielleicht nur mehr 5% von meinem Index, das ist die Frage.
Aber genau da springt der Optimizer dann ein von der Datenbank, weil der sich Histogramme und Statistiken auch von den Indizes speichert und der weiß, okay, der Großteil ist DE für Deutschland und der kleiner Teil ist AT und wenn jetzt in der Query AT gefragt wird, dann wird der Index zum Beispiel verwendet.
Also die Datenbank trackt es automatisch mit und bildet sich im Hintergrund Statistiken, wie denn die Daten eigentlich aufgebaut sind und entscheidet dann on the fly bei jeder Query, soll ich den Index verwenden oder nicht.
Und im Idealfall mit dem Land, wenn es um Österreich geht, würde er wahrscheinlich das Ganze verwenden.
Oder wenn man zum Beispiel ein Feld hat, der Status heißt aktiv oder nicht aktiv, dann hast du wahrscheinlich ganz viele aktive User und ganz wenige inaktive.
Das wäre auch so.
ein ganz ungleich verteilter Index, aber der macht natürlich auch Sinn, wenn du wirklich die nicht aktiven User rausfiltern willst, dass du den verwendest.
Hingegen, wenn du in der Wear-Clause drin hast, gib mir die aktiven, dann wirst du wahrscheinlich den Index gar nicht verwenden, weil einfach 99% der User sowieso aktiv sind.
Und das macht dann aber die Datenbank dementsprechend automatisch.
Okay, irgendwann, irgendwie trifft die Datenbank die Entscheidung, ich nutze diesen Index oder nicht, anhand von ihren Statistiken.
Jetzt können diese Statistiken ja auch out of date sein.
Und das Update dieser Statistiken kostet ja auch Rechenpower und Zeit und allem Drum und Drum.
Deswegen die Frage für mich, kann ich auch einen Index nicht nur auf die Spalte setzen, sondern auch auf Daten-Values?
Also könnte ich jetzt zum Beispiel in unserem Länderbeispiel den Index nur auf AT setzen, weil ich meine Daten so gut kenne und sage, wenn ich nach Deutschland query, da habe ich so viele Daten setze, da wird der Index sowieso nicht genutzt.
Um diesen ganzen Lookup.
auf die Statistiken und das Risiko, dass die Länderstatistiken out of date sind, zu vermeiden und mir all das spare?
Also klassisch in Datenbanken kannst du das nicht.
Es gibt natürlich spezielle Indexstrukturen, die das optimiert abspeichern.
Der Bitmap-Index zum Beispiel ist halt genau für diesen Use Case auch da, dass man zum Beispiel eben solche inaktiv-aktiv binäre Werte abspeichert.
Der würde das dann super optimiert abspeichern.
Er macht das trotzdem über die gesamte Tabelle, aber er speichert das optimal ab, dass eben...
die 99% aktiv nicht wirklich Zeile für Zeile gespeichert werden, sondern das Ganze optimiert abgelegt wird.
Also je nachdem, was du für Daten und Zugriffsmuster hast, musst du auch entscheiden, was für einen Typ von Index du hast.
Gerade wenn es im Hauptspeicher basiert, da hast du mehr Flexibilitäten, was du für Indexstrukturen verwenden kannst.
In der Datenbankwelt hast du meistens nicht so viele Möglichkeiten und die Datenbank...
macht das schon einigermaßen richtig, aber auch da kann man sich überlegen, kann ich den Hauptspeicherindex noch drüber setzen, einen speziellen Index-Hash zum Beispiel, den klassischen B-Tree, habe ich für Geostrukturen zum Beispiel, natürlich eigene Index-Strukturen oder eben einen Bitmap-Index.
Also da gibt es schon Möglichkeiten, aber grundsätzlich, wie du richtig sagst, Statistiken können outdated sein, sind eigentlich immer outdated, weil Statistiken halt nicht immer automatisch.
angepasst werden.
Also die sind nicht immer komplett live, weil das würde ja sonst zu viel Zeit benötigen und das sind ja nur Statistiken an sich.
Und wenn man sich diesen Optimizer anschaut in einer Datenbank, der arbeitet sowieso grundsätzlich immer auf Statistiken und Heuristiken.
Das heißt, der überlegt sich, okay, wie sieht meine Hardware aus?
Was habe ich für I.O., CPU?
Was habe ich da in meiner Query drinnen für Joins?
Muss ich irgendwas sortieren?
Was für Daten habe ich?
Was für Indizes habe ich zur...
und versucht dann alles in den Topf zu werfen, dann einmal umzurühren und dann die ideale Abfolge von Kommandos zu erstellen, die dann wirklich sagt, okay, probiere zuerst den Index, mit den Daten gehe ich dann auf den zweiten Index, dann fehlt dir nochmal über den dritten Index, dann gehe ich auf die eigentlichen Daten, dann mache ich die Sortierung oder nehme einen anderen Index, weil der sortiert mir das schon richtig.
Also ich habe da ganz, ganz viele Abfolgen und die eigentliche Kunst von Datenbanken ist dieser Optimizer.
Wie gut kann dieser Optimizer automatisch erkennen, was er machen muss, mit was für einem Kostenmodell funktioniert er.
Welche Informationen hat er überhaupt?
Das ist nochmal auch ein Problem, weil manche Optimizer nehmen vielleicht ganz klassische Festplatten an.
Du hast aber irgendwelche Hauptspeicher, NVEs, keine Ahnung, schlag mich tot, irgendwas.
Das muss die Datenbank natürlich auch wissen, weil sonst macht sie falsche Optimierungen.
Und das ist eigentlich...
So ein Grundproblem, was es natürlich gibt, aber für die klassische 0815 Hardware funktioniert das eigentlich ganz gut und wenn du dann alles mit berücksichtigst als Optimizer, Selektivität, Kardinalität, welche Daten überhaupt in meinem Index drinstecken, weil ein Index hat ja nicht nur eine Spalte, der kann ja zehn Spalten haben theoretisch, dann kommst du am Schluss auf einen idealen Pfad, den du abarbeiten kannst als Datenbank.
Und da musst du natürlich dem Optimizer ein bisschen helfen, weil der kann natürlich nur verwenden, was du auch erstellt hast an Indexstrukturen.
Welche Möglichkeiten habe ich denn dem Optimizer zu helfen?
Also in Bezug auf die Hardware zum Beispiel.
Du hast gerade gesagt, okay, wie teuer ist eine IA-Operation, CPU und pipapo.
Und je nach Hardware-Architektur ist das ja anders.
Vielleicht bin ich ja Hardware-Ingenieur.
Vielleicht möchte ich ja die Performance von einer Datenbank auf meiner CPU testen.
Vielleicht baue ich ja so eine CPU speziell für diese Datenbank-Workloads.
Also A, die erste Frage.
Kann ich der Datenbank, kann ich dem Optimizer helfen, indem ich die Kostenparameter des Optimizers in Bezug auf die Hardware tweaken kann?
Und B, macht das überhaupt Sinn, sich diese Frage zu stellen?
Also hat die überhaupt eine Relevanz im normalen Entwicklerumfeld?
Oder trifft das nur auf High-Performance-Sachen zu und Co.?
Also in erster Linie kommt es mal darauf an, was du für Datenbanksysteme verwendest.
Manche erlauben mehr Eingriff, manche weniger.
MariaDB hat zum Beispiel einen wesentlich transparenteren Optimizer als zum Beispiel MySQL.
Also da gehen sie zum Beispiel komplett auseinander.
Was du aber immer machen kannst, und das ist eigentlich mal die Grundlage, du erstellst die Indexstrukturen.
Das heißt, du entscheidest, welcher Index lebt und geupdatet wird.
Und damit kannst du eigentlich dem Optimizer am meisten helfen.
Das heißt, du stellst mal die Indexstrukturen zur Verfügung.
Der Optimizer entscheidet dann, verwende ich die oder verwende ich nicht.
Passt mir das ins Konzept?
Macht das Ganze schneller oder nicht?
Also diese Entscheidung macht der Optimizer, aber du gibst ihm schon mal das Futter überhaupt, weil ohne Index kann der Optimizer eigentlich wenig machen.
Jetzt in Bezug auf I.O.
und Hardware-technische Sachen, wie gesagt, manche Datenbanken erlauben, dass du da Informationen gibst, manche nicht.
Wie gesagt, der normal sterbliche Entwickler, Entwicklerin wird das nicht brauchen.
Was mir aber im Tagesgeschäft durchaus unterkommt, ist, dass man gewisse Hints gibt.
Also gerade wenn man sehr aufwendige Queries hat, dass man zum Beispiel irgendwelche Hints gibt, okay, jetzt verwende einen speziellen Index oder materialisiere zum Beispiel die Daten.
Also wenn du ganz komplexe Join-Reihen folgen oder mehrere Tabellen hast mit Commentable Expressions, dass du sagst, okay, jetzt baue mal die erste Tabelle zuerst zusammen und dann mache erst den nächsten Schritt.
Anstatt bauen einen riesen Plan zusammen, der die gesamte Query beantwortet, dass das so schrittweise gelöst wird.
Da sind die Optimizer teilweise überfordert und da kannst du so ein paar Hints geben mit so Kommandos, dass du eben sagst, okay, bau dir mal diesen Subteil zusammen von der Query und dann mach weiter.
Und da kannst du gewisse Sachen optimieren und noch Performance rausholen.
Der Nachteil ist auch da wieder, es kommt eine neue Version raus von der Datenbank.
Du machst ein Update, plötzlich ist der Optimizer viel intelligenter und deine Hints machen eigentlich die ganze Sache schlechter, als was der Optimizer das machen würde, der neue.
Also auch da ist wieder das Problem, dass das halt eine gewisse Art von Blackbox ist.
Zusätzlich, die ganzen Statistiken ändern sich ja ständig, deine Daten ändern sich.
Also auch da ist es schwierig.
Alles, was man dann so hardcoded, ist eher negativ, würde ich mal sagen.
Also ihr würdet den Optimizer schon einfach arbeiten lassen, weil die sind intelligent, da wird wirklich viel Zeit reingesteckt und die schauen sich dann wirklich die aktuelle Datenlage an und machen dann einen optimierten Ausführungsplan.
Ja, zusätzlich, wenn du dem Optimizer dann noch diese Hints gibst oder ich kenne das ab und zu von SQL-Quibs, den kannst du ja sogar forcen, nutze diesen Index.
Wenn du jetzt wirklich weißt, was du da tust, dann kann sich die Implementierung des Optimizers ja auch in der nächsten Version ab.
in der nächsten Version der Datenbank ändern.
Und dann sind wir genau wieder bei dem Beispiel, was du von deinem Kollegen da erzählt hast.
Die jagen irgendwelchen Performance-Degradations hinterher wegen einem Datenbank-Update oder ähnliches, weil der Optimizer sich unterunter geändert hat.
Also da ist ja die Frage, optimierst du hier auf eine innere Implementierung oder optimierst du auf Basis des Optimizer-Interfaces?
Das ist ähnlich wie ein Unit-Test.
Testest du das externe Interface oder testest du die innere Implementierung?
Und auch da würde ich wieder sagen, wenn du keinen Einfluss drauf hast, auf diese externe Implementierung, dann lass es einfach und nimm die an, dass die möglichst geschickte Sachen machen.
Also da die Trennlinie zu ziehen, wie bei allen anderen eben Tests oder so, genauso.
Alles, was extern ist, was ich nicht beeinflussen kann, versuche ich dann auch weniger zu beeinflussen, weil sonst hat man genau diese Seiteneffekte, wo man dann auch so mit Bugs ewig lang sucht.
Da hat man irgendwo einen Hint drinnen und alles wird langsamer und dann viel Spaß beim Suchen, weil der Hint ist irgendwo vor fünf Jahren mal eingegeben worden.
Ich frage mich gerade, was ist der Hauptfokus von Indizes?
Was optimieren die?
Optimieren die die algorithmische Ausführung oder optimieren die anhand von Tweaks, wie die Hardware genutzt wird?
Also IO und Co.
Denn wir haben über beide Areale bereits gesprochen.
Was würdest du sagen, ist der Hauptfokus eines Index zur Optimierung?
Die Grundidee, die habe ich auch ganz, ganz am Anfang schon erwähnt, ist, möglichst wenig Daten verarbeiten zu müssen, weil es dauert grundsätzlich am längsten.
Wenn ich irgendwelche Daten laden muss, vergleichen muss, wie sie im CPU mal landen, durch die ganzen Cache-Hierarchien, das braucht einfach.
Und das versucht ein Index in irgendeiner Form zu optimieren.
Aber wie auch am Anfang schon gesagt habe, ein Index ist immer die Datenstruktur selbst und der Algorithmus auf einer speziellen Hardware für eine spezielle Workload.
Und das muss ich alles mitdenken.
Also man kann nicht sagen, es wird nur eine Sache optimiert von den vier.
Du musst immer alles mitdenken.
Du kannst natürlich auch den Workload verändern und damit großen Impact auf die Gesamtzeit haben, auf die Ausführungszeit.
Also diese vier Punkte musst du immer gemeinsam betrachten, sonst funktioniert das nicht.
Und da ist natürlich auch ein großer Unterschied, wenn wir jetzt von der Hardware sprechen, sprechen wir von Sekundärspeicher, Festplatte oder von Hauptspeicher.
Weil da unterscheiden sich die Strukturen natürlich extrem, wie...
abgearbeitet wird, was schnell ist.
Da ist vielleicht ein Lookup sehr schnell im RAM.
Auf der Festplatte ist es langsamer.
Da habe ich andere Cache-Hierarchien, andere Geschwindigkeiten und dann muss ich natürlich schon ganz anders arbeiten mit meinem Algorithmus.
Ich habe vielleicht dieselben Daten irgendwo liegen, aber der Algorithmus muss dann anders arbeiten oder der Optimierer, weil du eine Operation vielleicht hast, die im RAM viel schneller ist als auf der Festplatte und du dadurch den Ablauf ganz anders machen kannst.
Da rentiert es sich vielleicht, ein paar Daten mehr zu lesen.
Weil schneller ist, dafür weniger abzuspeichern.
Der klassische Trade-off vom Speicherplatz und Geschwindigkeit zum Beispiel.
Du wirfst jetzt hier wieder mit Fachbegriffen um sich und erwartest von mir, dass ich hier im Vorlesungssaal sitze und wir haben Donnerstag und du referenzierst hier gerade eine Vorlesung von Dienstag.
Hauptspeicher, Sekundarspeicher.
Wolfgang, ich habe acht Stunden Arbeit hinter mir.
Ich bin gerade auf dem Weg vom Büro nach Hause im Auto.
Mein Gehirn ist schon gebrutzelt, weil mein Vorgesetzter wieder fünf Reportings haben wollte.
Also, explain me like I'm five.
Gib mir nochmal eine Einführungsvorlesung über die Unterschiede Hauptspeicher, Sekundarspeicher, damit ich dir auch mal folgen kann.
Sekundärspeicher heißt das mal.
Vielleicht ist das wieder so eine deutsche, österreichische Sache.
Sekundär, Sekundar.
Ja, egal.
Ich nenne es mal Sekundärspeicher.
Also grundsätzlich fährst du mal nicht zur Arbeit.
Du bist fully remote, Andi, aber gut, es kann trotzdem anstrengend sein.
Weil eigentlich kommst du wahrscheinlich gerade aus dem Garten vom Rasenmähen oder so, aber ich lasse dir mal deine anstrengende Arbeit.
Da packst du jetzt aber auch wirklich hier Stereotypen aus, wie Leute Homeoffice beschreiben, die nie Homeoffice machen durften.
So nach dem Motto, ach, die liegen ja eh nur im Garten.
Naja, ich habe eh nicht gesagt liegen.
Du machst ja eh viel im Garten Rasenmähen und so.
Aber gehen wir mal zurück auf den Hauptspeicher.
Also grundsätzlich, früher war das natürlich noch ein größerer Unterschied mit dem Sekundärspeicher, mit der Festplatte, mit der Spinning-Disk, weil die halt viel, viel langsamer war.
Also so ein Spinning-Disk hatte halt früher 300 Megabyte die Sekunde und heute bist du halt doch bei einigen Gigabit, die du vielleicht an den Durchsatz erreichen kannst.
Also das hat sich...
bisschen geändert.
Nichtsdestotrotz sind die Konzepte eigentlich noch dieselben.
Grundsätzlich überall, wo du auf Daten zugreifst, auf Speicher zugreifst, sei es jetzt auf der Festplatte oder im RAM oder im L1 Cache, du hast immer eine gewisse Größe, mit der du arbeitest.
Auf der Festplatte ist es die Seite, Page, die ist sehr groß üblicherweise.
Und wenn du irgendwas lädst von dieser Festplatte, von deinem Sekundärspeicher, dann musst du immer eine ganze Page laden.
Das heißt, wenn du jetzt einen Integer laden willst, dann sind das meistens wesentlich mehr Informationen, die du da immer mitlädst, automatisch.
Das heißt, du lädst deine Seite dann mit 4 Kilobyte oder vielleicht sogar noch mehr, ein paar hundert Kilobyte, wie das auch immer je nach Speichertyp funktioniert, aber du lädst mehr als nur diesen einen Integerwert, den du zum Beispiel haben willst.
Und das ist überall gleich, auch beim L2, L3 Cache.
Du lädst nie nur den einzelnen Integerwert.
Du lädst nun mal immer mehr mit außen herum.
Und mit dem musst du mal grundsätzlich arbeiten.
Also wie lokal liegen deine Daten, weil du kannst wirklich nie nur einen Integerwert laden.
Du kannst ihn natürlich schon, aber du musst alles andere wegwerfen.
Das heißt, wie lokal liegen deine Daten zusammen, die du gemeinsam brauchst.
Das ist so die Grundannahme von Indexstrukturen, dass du eigentlich diese Lokalität optimierst.
Im Hauptspeicher ist es halt eher die Cache-Lokalität, die Größen von den Caches und auf der Festplatte sind es eben diese ganzen Seiten, die du optimierst.
Das sind meistens größere Blöcke, die du da unter einmal lädst.
Was natürlich im Hauptspeicher schon nochmal eine andere Nummer ist, ist einfach die Geschwindigkeit.
Auch jetzt im Vergleich zu SSDs oder modernen, schnellen Sekundärspeichern.
Ich bin im RAM viel, viel schneller.
Ich kann viel mehr springen, weil eben meine...
Cache-Lines oder Blöcke, die ich adressieren kann, einfach viel kleiner sind.
Dadurch ist ein Sprung auch weniger teuer, weil du nicht immer, keine Ahnung, 4 KB laden musst, sondern nur 64 B oder so in meinen Cache-Card laden musst.
Also umso näher ich an der CPU bin, umso billiger sind meine Sprünge und umso mehr Pointer kann ich eigentlich verwenden.
Wenn jetzt meine Daten auf der SSD randomisiert irgendwo herumliegen, auch wenn man sagt, auf der SSD kann man ja trotzdem random springen, weil es ist ja keine Spinning Disc mehr wie früher, ist es trotzdem teuer zu springen.
Und wenn ich was zusammen habe und in einem Blog in einer Page lesen kann, bin ich trotzdem immer schneller.
Und genau da unterscheiden sich noch Sekundärspeicher zu Hauptspeicher.
Also wie sehr muss ich auf meine Lokalität achten, dass meine Daten zusammenliegen.
Und wenn man da wieder auf diese binäre Suche geht, die wir jetzt zum Beispiel schon gehabt haben, so eine der einfachsten Indexstrukturen im Hauptspeicher ist ja der Binärbaum.
Das heißt, ich habe einen Baum und bei jedem Knoten habe ich zwei Abzweigungen, einmal nach links, einmal nach rechts binär, kleiner oder größer.
Diese Struktur funktioniert natürlich nur im Hauptspeicher.
Das heißt, ich habe einen Knoten, mache einen Sprung nach links oder nach rechts und springe zu einer anderen Adresse.
So ein Binärbaum würde mich auf der Festplatte natürlich killen.
weil dieser Sprung von einem Knoten zum nächsten super teuer ist.
Und darum macht man zum Beispiel bei den Sekundär-Speicher-Index-Strukturen einen viel größeren Fan-Out auf so einem Knoten.
Das heißt, ihr habt auf so einem Knoten nicht nur einen linken und rechten Knoten, Kindknoten, sondern ihr habt zum Beispiel 200 Kindknoten.
Das heißt, ich kann unter einmal, wenn ich bei einem Knoten eine Überprüfung mache, wohin soll ich springen, dann kann ich 200...
Überprüfungen machen und meinen Suchraum in 200 Untersuchräume aufteilen.
Das ist der klassische B-Baum dann.
Also der Binärbaum teilt alles in zwei Subräume auf und der B-Baum üblicherweise in 200 in der Größenordnung.
Und dann lade ich mir einmal so einen Knoten von der Festplatte mit den 200 Kriterien.
Wohin soll ich jetzt springen?
Kann die auf einmal bearbeiten in meiner CPU, idealerweise so lange wie die Cache-Line.
kann das hochoptimiert prüfen und teile dann meinen Suchraum in 200 auf.
Und das ist dann üblicherweise schneller, weil ich natürlich einen höheren Logarithmus habe und dann schneller an mein Ziel komme.
Beim Binärbaum ist es nicht so schlimm, weil da kann ich schnell springen im Speicher.
Dafür ist das Ändern.
Wesentlich schneller, weil ich natürlich weniger umstrukturieren muss.
Ein B-Baum hat super komplexe Umstrukturierungsprozesse.
Wenn da irgendwas geändert wird, dann muss ich 18 Knoten umhängen und umbauen und so weiter.
Also es ist wesentlich komplexer.
Und das ist wieder der klassische Trade-off zwischen Hauptspeicher und Sekundärspeicher.
Das Umbauen ist vielleicht teurer.
Dafür bin ich beim Suchen schneller, beim Sekundärspeicher, beim B-Baum und beim Binärbaum ist es eben genau umgekehrt.
Wenn ich als Softwareentwicklerin die ganze Sache nutze, dann sind ja so viele Sachen abstrahiert.
Wie kann ich das überprüfen, was du jetzt gerade gesagt hast?
Mache ich immer zeitliche Messungen oder kann ich mir die Datenstruktur effektiv ansehen durch einen simplen Unix-Command oder ähnliches?
Du brauchst das Hintergrundwissen.
Also du musst mal grundsätzlich verstehen, was bedeutet ein Binärbaum, was bedeutet ein B-Baum, welche Index-Strukturen verwendet meine Datenbank, welche verwende ich für mich im Hauptspeicher zum Beispiel, wenn du eine Hash-Map...
verwendest, musst du ja auch verstehen, was macht diese Hashmap und eine Hashmap ist auch nichts anderes als eine Indexstruktur im Hauptspeicher.
Die erlaubt mir einen schnellen Lookup, ohne dass ich ganz viele Daten laden muss.
Also es ist genau dasselbe und du musst es einfach verstehen, damit du es auch verwenden kannst.
Also ich muss ja auch nicht verstehen, wie ein Benzinmotor funktioniert, um Auto zu fahren.
Ja, du kannst natürlich einfach sagen, okay, der AI-Agent meines Vertrauens hat mir gerade vorgeschlagen, eine Hashmap zu verwenden.
Klar, kannst du verwenden.
Es wird schnell sein.
ist vielleicht ausreichend.
Wenn du ein Problem hast, wenn du in die Tiefe gehen willst, musst du natürlich verstehen, was ist eine Hashmap, wie funktioniert ein Hash, was sind die Nachteile.
Kannst du natürlich auch schmerzvoll einfach rausfinden, wenn du irgendwann mal dann gegen die Wand läufst und alles langsam wird und du musst dann mühsam rausfinden, okay, es ist die Hashmap und es gibt irgendwie Kollisionen in der Hashmap und darum wird alles langsam oder du verstehst es halt grundsätzlich oder eignest dir das Wissen an oder fragst mal deinen Agent, hey, du hast mir deine Hashmap vorgeschlagen, warum, was ist eine Hashmap?
und erkläre mir kurz Vor- und Nachteile.
Und dann lisse ich diese drei Sätze und habe die Information.
Das ist halt dann der Unterschied, hole ich mir die Information, verstehe ich das einigermaßen, was im Hintergrund passiert, oder mache ich einfach Vibe-Coding.
Naja, also da beleide ich es ja jetzt aber sehr, sehr viele Leute.
Zwischen Vibe-Coding und ich weiß genau, wie unten drunter eine Hashmap die Daten organisiert, da liegen halt schon noch ein paar Level, ne?
Ich sage nicht, dass man das bis ins tiefste Detail verstehen muss, aber eben diese...
Simple Frage, Agent, erklär mir mal kurz Vor- und Nachteile, wie das so grob funktioniert.
Ich rede ja von diesem Verständnis und mehr brauchst du ja auch gar nicht verstehen.
Du musst ja jetzt nicht wissen, wie werden Kollisionen wirklich im Detail aufgelöst in dieser Hash-Map, aber du musst wissen, wenn ich ganz viele Kollisionen habe, dass das Ganze langsamer wird.
Also solche Grundinformationen, habe ich einen Key, wo ich viele Kollisionen habe, dann wird das Ganze langsamer üblicherweise.
Und solche...
Grundsatzinformationen und Verständnis von Indexstrukturen, das ist natürlich hilfreich, wenn man die einfach hat, was das bedeutet.
Ich verstehe jetzt auch nicht im Detail, wie der neueste Redix-Tree irgendwie die L1 bis L3-Cache-Optimierung macht und wie lang die Zeilen im Detail sind.
Aber ich weiß grundsätzlich, dass es da Optimierungen gibt und man kann ja dann auch sehr schnell nachschauen, welche Indizes sind für was geeignet, Hauptspeicher, Sekundärspeicher, was ist besser, was ist schlechter.
Und so ein Grundverständnis hilft dann schon im Alltag, meiner Meinung nach.
Jetzt habe ich dich initial so angekündigt als jemand mit Doktortitel in Datenbanken.
Und gegen Ende dieser Episode zerstörst du deine Credibility, indem du sagst, ja, ich weiß auch nicht, wie das unten drunter funktioniert.
Wolfgang, so funktioniert Podcasting nicht.
Ist wahrscheinlich das Problem von dem wissenschaftlichen Ansatz, weil wenn du mal so Papers von der VLDB zum Beispiel durchliest, da weißt du einfach, dass du eigentlich dann keine Ahnung hast.
irgendeine Indexstruktur, die das Delta vom Delta vom Delta dir vorrechnet und zeigt und irgendwelche Optimierungen macht auf der Indexstruktur und du hast keine Ahnung mehr, von was die eigentlich sprechen, dann merkst du, obwohl du da viele Jahre verbracht hast in dem Bereich, dass es dann schon unter Umständen auch Sachen gibt, Ebenen gibt, die so tief liegen, die du nicht verstehst und dann kann man das auch akzeptieren, dass man die nicht versteht.
Aber so grundlegende Optimierungen sind schon ganz hilfreich.
Und dann am Ende sucht man sich einfach raus, was gut funktioniert.
Aber dass es mal zum Beispiel Hauptspeicher und Sekundärspeicher gibt, dass es da einfach unterschiedliche Indexstrukturen auch gibt, wenn ich einen klassischen Red-Black-Tree oder Aval-Tree für den Hauptspeicher verwende, binär, baum und eben einen klassischen B-Baum, dann bin ich schon mal eigentlich ganz gut am Weg und habe schon relativ viel verstanden.
Lass mich nochmal auf die ganzen Abstraktionen zurückkommen, denn...
Du hast das gerade so abgewunken.
Ja, dann promptest du halt mal mit der KI so ein bisschen und dann musstest du halt verstehen, da kann ich dir jetzt auch nicht helfen.
Ja, da merkt man schon, du bist so ein typischer Professor, der vorne unten im Hörsaal steht und einfach keinen Bock mehr hat, weil die alle zu dumm sind.
Verstehe ich.
Nehme ich gerne an, ja, aber ich lasse das jetzt nicht auf mir sitzen für die ganze Hörerschaft hier.
Deswegen, wenn ich all das selbst programmiere, da kann ich mich da so tief reinnerden, kann meine Structs optimieren, Cash-Line, Cash-In-Linen und Pipapo.
Aber in meiner Postcray, in meiner MySQL, in meiner MariaDB, in meiner Oracle, in meiner Whatever-Datenbank mache ich Create Index, freue mich, dass du um 12 Uhr Mittagessen gibst und gehe in die Pause.
Also lass uns die ganze Thematik doch mal bitte praktisch machen und den Leuten hier nicht immer Hausaufgaben geben.
Verstehe, wie halt eine Hashmap funktioniert und dann wird das schon alles besser.
Nee, so funktioniert das nicht, Herr Akademiker.
Also, drei praktische Tipps, die du mir jetzt mitgeben kannst, die ich jetzt heute Abend auf mein Zeitprojekt anwenden kann.
Also erstens, ich bin kein Professor, nur um das klarzustellen.
Trotzdem habe ich diese Ansicht.
Aber du verhältst dich ja genau so wie einer.
Trotzdem bin ich der Meinung und wenn du mir jetzt konkret nach drei Tipps fragst, wäre für mich schon ein Tipp, grundsätzlich Sachen besser verstehen zu wollen.
Und gerade in der heutigen Zeit ist es eigentlich wichtig, dass man die Sachen besser versteht.
Und wenn du jetzt sagst, okay, in meiner Postgres...
Da kann ich ja nichts ändern, da mache ich nur Create Index.
Das stimmt schon, aber du kannst in der Postgres erstens mal auswählen, ob du ein Btree machst, ein Has, ein Gist, ein Chin, ein B-R-I-N, einen Blumenindex über eine Extension.
Also du hast schon auch bei Postgres die Wahl, was für Indexstrukturen du wirklich verwendest und dann musst du die Indexstrukturen verstehen und wissen, auch da wieder, was für einen Workload hast du und wie wendest du den Index an.
Zusätzlich hast du jetzt auch, wenn wir mal ganz klassischen Index verwenden im B-Tree, der halt so überall der Allround-Index in der Datenbankwelt ist, auch da kannst du entscheiden, welche Spalte ist in meinem Index.
Welchen Index erzeuge ich denn überhaupt über welche Spalten?
Da kommen dann diese ganzen Zugriffsmuster nämlich auch nochmal ins Spiel.
Du kannst ja mehrere Spalten in dem Index hinzufügen und wenn du zum Beispiel jetzt zusätzlich zu deiner E-Mail-Adresse, wenn wir wieder auf das Beispiel zurückkommen, immer den Namen haben willst.
Also du suchst eine E-Mail-Adresse und willst dann den Namen an die haben, an die Grundwald.
Dann kannst du in diesen Index die E-Mail-Adresse hinein speichern als Spalte.
Die Sortierung läuft dann über die E-Mail.
Und als zweite Spalte noch den Namen.
Dann beinhaltet nämlich dieser Index die E-Mail-Adresse und den Namen und covert diese zwei Spalten.
Und für eine Anfrage über die E-Mail-Adresse, gib mir den Namen, brauchst du dann die eigentlichen Daten gar nicht.
Das heißt, du kannst die Anfrage ausschließlich über den Index beantworten.
Und solche Dinge helfen dir natürlich im Alltag weiter, weil dann sparst du dir wieder einen kompletten Zugriff auf die klassischen Daten.
Wir können mal eine eigene Episode zu Optimierungen ganz allgemein machen, welche Indexstrukturen man verwendet und wie man dann optimiert im Speziellen.
Aber ganz allgemein kannst du sehr wohl viel machen.
Im Hauptspeicher hast du sowieso alle Möglichkeiten.
Da kannst du ja machen, was du willst.
Vielleicht sollst du nicht alles selber programmieren vom Scratch.
Also du wirst es jetzt lernen.
Ich würde auch keine Hashmap neu implementieren, sondern eine Hashmap verwenden.
Aber dass man einmal weiß, was kann man überhaupt verwenden?
Was gibt es für Indexstrukturen?
Welche passen für meinen Use Case?
Und wie wende ich sie richtig an?
Weil wie gesagt, der B-Tree ist zwar fix in...
eine MySQL oder eine Postgres, das Standard Index, aber ich habe ja trotzdem viele Möglichkeiten, wie ich den dann auf meine Daten anwende.
Und da hilft mir dann schon das Grundverständnis, wie ein Index funktioniert und was ich dann mit meinem Index machen kann.
Und ich kann mir dann das über Explain Statements zum Beispiel auch ausgeben lassen, um das dann vielleicht zu optimieren, um mal zu schauen, wie funktionieren meine Zugriff-Patterns, welche Index-Strukturen werden überhaupt verwendet vom Optimizer.
Und da kann ich wirklich konkret ansetzen.
Und meiner Meinung nach muss man da auch konkret ansetzen.
Weil genau diese Stellen sind die Möglichkeiten für uns EntwicklerInnen, da Einfluss zu nehmen.
Auf dem Optimizer Einfluss zu nehmen, das ist dann schon Next Level.
Aber mal grundsätzlich zu entscheiden, was für Indexstrukturen verwende ich, welche Spalten klatsche ich da rein, was habe ich für einen Workload.
Also dieses Vierergespann von Datenstruktur, Algorithmus, Hardware und Zugriffsmuster zu kennen, zu verstehen und anzuwenden, macht meiner Meinung nach am meisten Sinn.
Und sich da vielleicht mal...
jetzt im Site-Project konkret anzuschauen, was habe ich denn überhaupt für einen Index?
Was verwende ich da für einen Index?
Kenne ich überhaupt die Indexstruktur?
Was sind meine Zugriffsmuster und kann ich da was optimieren?
Das wäre so mein Plan, wenn ich an irgendwas rangehen will, um mal zu schauen, habe ich irgendwo ein Problem in meiner Implementierung?
Kann ich wo was schneller machen, wenn ich in diese Richtung wirklich gehen will?
Du hast gerade sehr viel über die Erstellung von Indexen gesprochen.
Indexe?
Indizes?
Geht beides.
Das ist ja fast mit Greenfield gleichzusetzen.
Ich habe eine neue Tabelle.
Die ist noch ganz jo-fräulich.
Du kannst ja Indizes jederzeit erstellen und löschen.
Ja, ja, richtig.
Nur, jetzt ist es ja so, Legacy verdient das Geld.
Und wir arbeiten ja alle in einem Team an einer großen Applikation.
Mit hoher Wahrscheinlichkeit existieren schon Indizes oder Indexe oder keine Ahnung, wie das Wort jetzt heißt.
Würdest du mir auch empfehlen, quartalsweise alle Indexe zu reviewen und zu schauen, ist die Annahme noch konkret?
Oder würdest du auch empfehlen, die Annahmen pro Index als SQL-Kommentar ins Schema mitzupacken oder ähnliches, weil es hört sich so an, als wären die Indexe auf Basis von Annahmen erstellt, ähnlich wie damals Designentscheidungen in deinem Code getroffen wurden.
Also so Architecture Decision Records für Indizes oder ähnliches.
Oder ist das ein bisschen over the top?
Willst du jetzt meine wissenschaftliche oder meine pragmatische Herangehensweise hören?
Ich will eine Antwort auf meine Frage.
Also grundsätzlich ist es so wie überall.
Pragmatisch würde ich sagen, wenn du kein Problem hast, mach einfach nichts.
Wenn das schnell läuft, dieses Ding, und du nirgends Schmerzen hast, dann ändere nichts.
Das kannst du immer noch machen, wenn du Probleme hast.
Aber was natürlich schon gut wäre, wäre ein grundsätzliches Monitoring von dem Ganzen.
Wie schnell sind denn meine Abfragen überhaupt auf der Datenbank?
Wie viel CPU-Load hat meine Datenbank und wie viel die eigentliche App zum Beispiel?
Also solche Grundsatz...
Metriken mal zu haben, sind schon gut.
Und wenn ich dann eine Fleißaufgabe machen würde und das ist dann die wissenschaftliche Herangehensweise oder ich will was lernen oder ich habe einfach so viel Zeit, weil die LLMs meine Arbeit machen und ich so viel Freizeit habe, dass ich da tief eintauchen kann, dann kann man sich natürlich so ein Review mal überlegen, welche Indexstrukturen habe ich überhaupt, brauche ich welche, gibt es vielleicht so einen Slow Query Log zum Beispiel, was sind meine langsamen Anfragen, kann ich da irgendwo was beschleunigen?
Es schadet natürlich nie, da mal reinzuschauen, wenn man sowas hat.
Aber wie gesagt, wenn man kein Problem hat, würde jetzt auch keines künstlich da kreieren grundsätzlich.
Ja, es geht ja nicht nur um Probleme lösen, es geht ja teilweise auch um Bildung, es geht ja teilweise auch um Optimierung von low-hanging fruits.
Und besonders, wenn wir Web-Applikationen bauen, wissen wir ja alle, jede Millisekunde zählt.
Also von daher weiß ich gar nicht, ob man hier immer nur Probleme löst oder nicht wirklich gute Optimierung macht, um vielleicht dann die Conversion zu steigern.
Was mir auch oft passiert ist, wenn ich wirklich auf die Datenbank bei manuell irgendeine Query absetze und die so gefühlt irgendwie fünf Sekunden warte und mir denke, das ist schon irgendwie komisch langsam, auch wenn es nur eine Log-Tabelle oder irgendwas ist, dann schaue ich mal kurz rein, gibt es da eigentlich Indizes, habe ich da die Richtigen, könnte ich da vielleicht einen Index schnell drüberlegen.
Man muss auch aufpassen, gerade wenn man so riesige Tabellen hat und plötzlich einen Index erzeugt, kann es sein, dass man die ganze Datenbank lockt oder einen Großteil oder vielleicht da auch produktiv was kaputt macht, also da muss man auch aufpassen.
Aber wenn ich Anzeichen sehe in irgendeiner Form, sei es jetzt Slow Query Log oder persönlich, dass irgendwas langsam läuft, wenn ich eine Ad-Hoc-Query abfeuere, dann schaue ich vielleicht mal kurz rein, wenn ich Zeit habe.
Und teilweise ist es ja wirklich nur fünf Minuten und man sieht, okay, ist jetzt ein Index, der viel helfen würde, ist vielleicht keine Riesentabelle, die jetzt alles langsam machen würde mit dem Index und dann probiere ich das einfach mal aus.
Jetzt gibt es aber noch ein Problem.
Ich habe diese Episode gehört.
Es gibt keine Probleme, es gibt nur Challenges, Andi.
Ich mag dein positives Wording.
Danke, dass du mich daran erinnerst.
Ich habe diese Episode jetzt gehört.
Verinnerlicht.
Ich habe mir sogar Notizen gemacht.
Ich schaue auf mein Datenbankschema.
Ich habe gelernt, Indexe zu maintainen.
Kann teuer sein.
Nicht jeder Index bringt noch was, weil vielleicht die Datenannahme nicht mehr stimmt.
Dann gibt es ja das Problem, wenn ich jetzt meine Datenbank anpasse, mein Schema anpasse.
Ich nehme den Index weg, ich droppe den und der war vielleicht doch noch in Benutzung von irgendeiner von irgendeinem anderen Service und der ist jetzt ganz langsam, dann kann ich den ja nicht einfach so wieder hinzufügen.
Klar, also ich kann die Query absetzen zu, oh, pack den mal wieder dahin.
Aber das kann ja auch einen großen Performance-Impact auf die DB haben, oder?
Ja, aber das hat jede Änderung.
Du kannst ja auch am Code irgendeinen Scheiß bauen.
Ja, ja, richtig.
Nur der Unterschied ist, dass du halt, um nichts wieder hinzuzufügen, sehr wahrscheinlich eine harte Last auf die DB setzen kannst.
Und somit Produktiv-Traffic.
beeinflussen kannst und so weiter und so fort.
Meine Frage ist eigentlich, sollte man deswegen keine Indizes droppen?
Also ich meine, das geht schon alles in die Richtung, so nach dem Motto, wenn du Angst hast, eine Änderung zu machen, ist das schon sehr problematisch.
Egal, ob es wir an Source Code oder Datenbanken ernannt, aber das hat ja wirklich jetzt einen schwierigen Impact.
Naja, das kann eigentlich schon überall sein.
Ich glaube nur, dass wir die Sicherheitsnetze natürlich, wenn es um Programmcode-Änderungen geht, schon aufgebaut haben und wir haben selten diese Sicherheitsnetze bei der Datenbank.
Weil du kannst natürlich diese Test-Szenarien genauso mit der Datenbank auch fahren.
Du kannst ja mal einen Index löschen und dann, wenn du einen sauberen Test-Workload hast, den mal abfeuern und schauen, ist die Datenbank jetzt immer noch gleich schnell?
Gibt es ein Problem?
Also du kannst es ja auch mal im Vorhinein testen.
Du kannst natürlich so high-sophisticated-Szenarien haben wie einen Proxy-SQL, der dir den gesamten Datenbank-Traffic nochmal kopieren kann und an einen anderen Server schicken.
Dann löscht du dort diesen Index und schaust mal.
läuft der Server immer noch gleich weiter mit dem gleichen Load.
Mit dem Live-Load hast du das Ganze aber dupliziert.
Also wenn du natürlich große Strukturen hast, dann kannst du da schon was machen.
Und sonst kannst du es im kleinen Lokal natürlich auch testen.
Und ich würde mal sagen, wenn du sehr, sehr groß bist, dass das ein Problem ist, dann hast du vielleicht schon Strukturen, um solche Sachen zu testen.
Und wenn du klein bist, hast du wahrscheinlich kein Problem, weil deine Datenbank einfach nicht so groß ist.
Und im Idealfall ist deine Datenbank sowieso nicht jetzt auf Anschlag.
Und wenn du das dann in der Nacht machst, dann erzeugst du den Index halt wieder oder deine Datenbank ist mal langsam über eine gewisse Zeit.
Index erstellen ist normal gar nicht so das Problem, weil das relativ gut asynchron eigentlich funktioniert.
Und grundsätzlich, um deine Frage zu beantworten, sollte man nie droppen.
Grundsätzlich, jeder Index braucht Performance, weil er immer abgedatet werden muss.
Wenn du jetzt ganz viele Indexstrukturen hast, die du updaten musst, du brauchst sie aber gar nicht, dann ist deine Datenbank wesentlich langsamer.
Also es würde jetzt nicht unterschätzen, was das eigentlich ausmachen kann, einen Drop zu machen.
Ja, ich spreche nur diese Herausforderung an, die ich halt schon in Firmen gesehen habe.
Du hast halt irgendwelche Systemadministratoren, die kümmern sich halt um die Datenbank und die haben dann immer Angst, einen Index zu droppen, weil sie all die Details nicht wissen, wie eine Hashmap aufgebaut ist und so weiter und so fort.
Über all das, was wir hier gesprochen haben.
Also advocatest du eigentlich dafür, dass man ein ordentliches Staging-System hat, wo man ordentliche Load-Tests fahren kann mit Sicherheitstests, also ähnlich wie bei Code?
Ist das richtig?
Im größeren Setup sicher, ja.
Das ist immer die Frage, hast du die Kapazität, sowas zu machen?
Aber klar, grundsätzlich gehört das natürlich zu einem guten Test dazu.
Funktioniert auch mein klassischer Workload noch.
Mit dem Code, mit der Datenbank ist ja alles ein System und ich will ja eigentlich alles testen, genau wie du bei Observability halt Metriken aus allen Bereichen haben willst.
Du willst ja, wenn du jetzt einen Redis hast, der übrigens auch Datenstrukturen hat und eigentlich fast eine Datenbank ist.
Aber das ist nochmal eine andere Diskussion.
Dann willst du ja auch Metriken von Redis haben.
Du würdest ja nie sagen, ich mache nur die Metrik ganz, ganz vorne auf der App-Seite.
Alles andere ist mir egal.
Sondern du suchst ja schon hoffentlich dir die richtigen Metriken raus und von allen Systemen, die du hast, hast du einen groben Überblick zumindest, wie die funktionieren.
Sind sie auf Anschlag?
Gibt es Probleme?
Und dann kannst du auch ein bisschen besser dementsprechend agieren.
Ja, das, was du da erzählst, das ist alles richtig und ist auch in 2026 immer noch korrekt?
Ist aber auch irgendwie so eine Gedankenstruktur von 1990.
Denn du hast gerade gesagt, in großen Setups, und wenn du dir das leisten möchtest, kannst du dir ein Sicherheitsnetz für Datenbanken aufbauen.
Ja, es ist schon viel Arbeit, wenn du da so eine Infrastruktur aufbaust, wo du zweite Datenbank hast, alles spiegeln kannst, Workloads abfeuern kannst.
Also es ist nicht zu unterschätzen, würde ich mal sagen.
Ich habe eine pragmatischere Lösung für dich.
Und zwar habe ich diese Frage nicht ohne Grund gestellt.
Ich habe mir gedacht, in etlichen Episoden haben wir...
Dad-Jokes, Programming-Dad-Jokes gebracht.
Hier habe ich jetzt einfach mal die Suchanfrage gestartet.
Was ist denn so der skurrilste Index-Type, den so eine Datenbank eigentlich hat?
So nach dem Motto, um mal ein bisschen Humor hier reinzubringen, nach den ganzen Hashmap-Thematiken und so.
MySQL hat mir geantwortet.
Bei MySQL gibt es inzwischen einen unsichtbaren Index.
Dieser unsichtbare Index wird vom Optimizer komplett links liegen gelassen.
Der wird gepflegt von der Datenbank, der wird geupdated, der wird...
Der löscht Records, alle kommen dran.
Nur der wird vom Optimizer komplett links liegen gelassen.
Und da fragt man sich so, hä?
Warum gibt es diesen Index-Type denn überhaupt?
Warum macht der Load auf die DB, er wird vom Optimizer nicht verwendet?
Ja, stellt sich heraus, du kannst einen Index sichtbar und unsichtbar schalten.
Innerhalb von Millisekunden.
Und das ermöglicht natürlich genau das, was du da gerade angesprochen hast.
Performance-Testing von, wird dieser Index noch benötigt?
Bedeutet, du kannst jetzt zum Beispiel auf deiner MySQL-Datenbank hingehen, auf irgendeine Tabelle, schaltest einen Index auf unsichtbar, misst die Performance und wenn es eine Performance-Degradation hat, schaltest du ihn wieder auf sichtbar.
Ich weiß jetzt gerade leider nicht, ob das in anderen Datenbanken auch der Fall ist, aber ich habe den jetzt mal für MySQL zumindest mit in die Shownotes gepackt.
Ich meine, das lasse ich dann als Hausaufgabe für die Hörerinnen und Hörer, ob es sowas gibt, aber da muss ich zugeben, schon irgendwie geil.
Und das kannst du dann schon...
wirklich, ich sag mal so, Testing in Production machen?
Vielleicht in so einer Low-Traffic-Zone, morgens um 8 oder so oder abends um 8?
Kannst du einfach mal einen Index auf Invisible stellen?
Ja, du kannst auch in einer High-Traffic-Situation machen, weil du es ja recht schnell wieder zurückstellen kannst.
Und dieses Feature, cool, dass du das aufgebracht hast, weil es gibt es schon eigentlich sehr lange.
Das gibt es, glaube ich, schon 10 Jahre oder so grundsätzlich bei MySQL.
Also es ist ein cooles Feature, was man da verwenden kann, ja.
Acht Jahre gibt es das Feature.
Kam in MySQL 8 rein, aber nah dran.
Aber ja, kannte ich auch noch nicht.
Fand ich wirklich cool.
Invisible Indizes.
Nun gut.
Und mit diesem Knowledge Byte würde ich mal sagen, verlassen wir diese Episode.
Wer jetzt noch dran ist, harten Respekt.
Ich hoffe, euer Gehirn ist nicht zu sehr frittiert.
Und ihr habt als Hausausgabe mitgenommen, wie wird eigentlich eine Hashmap aufgebaut.
Fun Fact, wir haben uns auch mal überlegt, eine Episode zu machen, wie baut man eigentlich eine Hashmap, beziehungsweise wie funktioniert eine Hashmap unten drunter.
Haben wir dann aber wieder weggeschmissen, weil ohne Whiteboard ist das echt kompliziert zu erklären, weil du musst echt viele Pfeile zeichnen und nur auf Audiospur, da kann man nicht wirklich folgen, beziehungsweise wir haben uns nicht zugetraut, das ordentlich zu erklären.
Na ja, Dr.
Wolfgang Gastler, vielen lieben Dank für diesen Datenbank-Exkurs.
Ich habe jetzt erstmal die Schnauze voll von irgendwelchen Indizes.
Ich werde heute keinen mehr anlegen, wahrscheinlich die ganze Woche nicht.
Ja, ich glaube, wir müssen mal eine Episode wirklich konkret zu den Indexstrukturen machen, die es so gibt, damit wir das mal auch, weil es gibt schon coole Sachen, so ein Blumenfilter zum Beispiel oder die ganze Radix-Try-Geschichte, Patricia-Trys und so weiter.
Es sind schon coole Indexstrukturen und es ist schön, was man da nicht so machen kann.
Es ist immer so die Beauty of Index.
Aber vielleicht bin ich da anders gebollt.
Ja, ich finde das schön, was manche Leute so cool finden.
Ich finde ein Volksfest cool, wo es günstig Bier gibt.
Du, Blumenfilter.
Okay, lassen wir so stehen.
Und mit diesem Statement würde ich sagen, wir verabschieden uns und hören uns nächste Woche.
Bis bald.
Bye-bye.
Ciao.
