Ohne Index muss die DB die ganze Tabelle lesen, um die passenden Zeilen zu finden (Full Table Scan).
Warum Ein neues Feature bringt eine Suche nach einer nicht indizierten Bedingung mit → Folge Millionen Zeilen werden komplett gescannt, eine einzige Query dauert mehrere hundert ms bis einige Sekunden → Auf dem Bildschirm Postfach und Handelsverlauf laden langsam, belegte Verbindungen lassen auch andere Anfragen warten
Ausführungsplan neuer Queries vor dem Deployment prüfen, Indizes ergänzen, auch bei ändernden Queries (UPDATE, DELETE) prüfen, ob sie einen Index nutzen.
Aufgaben Infrastrukturteam
Slow-Query-Log überwachen, Queries mit Full Table Scan ermitteln und an das Entwicklungsteam weitergeben, Indizes im laufenden Betrieb online mit kurzen Locks anlegen.
Größenordnungen
Mit Index einige ms. Ohne Index wächst die Dauer mit der Datenmenge, bei großen Tabellen auf das Hundert- bis Zehntausendfache.
Im Graphen
Stufe ab einem bestimmten Zeitpunkt · DB-Query-Latenz, gelesene Zeilen
Wo nachsehen
MySQL: Rows_examined und Rows_sent im slow query log (mit log_queries_not_using_indexes werden auch Queries ohne Index protokolliert) sowie SUM_NO_INDEX_USED und SUM_ROWS_EXAMINED in performance_schema events_statements_summary_by_digest prüfen, EXPLAIN ausführen. PostgreSQL: seq_scan und seq_tup_read in pg_stat_user_tables prüfen, EXPLAIN ausführen
Spricht dafür
Eine nach dem Deployment neu aufgetauchte Query liest mehrere tausend Mal so viele Zeilen (Rows_examined), wie sie zurückgibt (Rows_sent), EXPLAIN zeigt einen Full Table Scan (MySQL type ALL, PostgreSQL Seq Scan). seq_tup_read großer Tabellen steigt ab dem Deployment steil an
Spricht dagegen
Index wird genutzt, trotzdem langsam: Warten auf Locks (db-hot-row, db-ddl-lock) oder geänderter Ausführungsplan (db-plan-flip). Ein Full Table Scan auf kleinen Tabellen kann normal sein
Prüfmittel
Mit Infrastruktur-Tools prüfbar (ohne Spielcode)
Mehr dazu
Auch Schreibvorgänge leiden darunter. Ändernde Queries ohne Index (UPDATE, DELETE) sperren je nach DB auch alle gescannten Zeilen und können so das Speichern völlig unbeteiligter Spieler blockieren.
Quellen
How MySQL Uses IndexesMySQL Ohne Index liest die DB die ganze Tabelle ab der ersten Zeile, je größer die Tabelle, desto teurer
Locks Set by Different SQL Statements in InnoDBMySQL Fehlt ein passender Index und wird die ganze Tabelle gescannt, werden alle Zeilen gesperrt, und selbst Einfügungen anderer Benutzer werden blockiert
The Slow Query LogMySQL Protokolliert Queries, die long_query_time (Standard 10 s) überschreiten; Queries ohne Index lassen sich zusätzlich protokollieren
CREATE INDEX (PostgreSQL Documentation)PostgreSQL Mit CONCURRENTLY entsteht der Index, ohne Schreibvorgänge zu blockieren; die normale Erstellung blockiert Schreibvorgänge bis zum Ende
Statement Summary TablesMySQL events_statements_summary_by_digest: SUM_NO_INDEX_USED (Anzahl der Ausführungen ohne Index) und SUM_ROWS_EXAMINED je Gruppe gleich aufgebauter Queries
EXPLAIN Output FormatMySQL type ALL bedeutet Full Table Scan, meist durch einen zusätzlichen Index vermeidbar