Grundsätzlich würde ich sagen, dass Felder für Verknüpfungen von Tabellen immer indiziert werden sollten.
Richtig, und zwar unbedingt. In Datenbanksystemen welche Relationale Integrität unterstützen, sprich Constrainst über Primary- und Foreign Keys können bei fehlenden Indizes auf Foreign Keys sogar dramatische Locksituationen eintreten. Z.b. wenn ein Update auf die Kopftabelle gemacht wird ( enthält PK ) wird die koplette Details Tabelle ( mit FK ) gelockt und für den Zugriff durch andere Benutzer gesperrt.
es kommt im Wesentlichen nicht darauf an wie das Verhältnis zwischen Schreib- und Lesezugriffen ist. Viel wichtiger ist, wie lange dauert der Zugriff beim Lesen bzw. in welcher Zeit muss das Ergebnis zur Verfügung stehen.
Jein. Sicher spielt die erwartete Anwortzeit eine Rolle, besonders in OLTP Applikationen. Man darf den Overhead von Indizes bei DML aber nicht vernachlässigen. Bis zu 30% Performanceeinbruch bei Update, Insert und Delete sind pro Index zu kalkulieren. Hat man also sehr sehr viele Änderungen im Vergleich zu Abfragen macht es Sinn über eine Art Staging Area nachzudenken, also die reinen Daten mit mögl. wenig Indizes, und andere ( mgl. verdichtete ) Datentabellen mit Indizes für die Abfrage, allerdings mit Zeitversatz. (In Oracle heist so eine Lösung beispielsweise Materialzed View oder MView)
Wird eine Abfrage z. B. einmal im Jahr gemacht und es spielt keine Rolle, wenn die Antwortzeit 1 Stunde ist, kann man auf den Index verzichten
Nun, 1xpro Jahr ist natürlich extrem selten, man darf aber auch nicht vergessen, dass eine schlechte Abfrage an die Datenbank die komplette Performance der Applikation auch für längere Zeit in die Knie zwingen kann. Grund:
Eine Abfrage ohne Index erzeugt einen FULL TABLE SCAN, sprich jeder Satz in der Tabelle muss mindestens einmal gelesen werden. Bei Joins und Sortieroperationen müsssen zudem oft noch Daten auf der Platte ausgelagert werden. Jede Datenbank hat einen Buffer in dem häufig genutze Daten gehalten werden um Anfragen schneller abzuarbeiten. Führt man nun einen umfangreichen FULL TABLE SCAN durch wird ein großer Teil des Buffers dafür genutzt und die häufig verwendeten Daten rausgeworfen. Das führt dazu, dass nach der schlechten Abfrage auch die anderen Abfragen erst warten müssen bis die Daten wieder von der Platte in den Buffer geladen wurden.
die meisten Datenbanken stellen Analysetools zur Verfügung, mit denen untersucht werden kann, wie lange was dauert.
Interessant sind hier die sog. Execution Pläne. Die Datenbank erzeugt für jede Abfrage einen solchen Plan in dem versucht wird den bestmöglichen Zugriff auf die Daten zu sichern. D.h. welcher Index wird verwendet, welches SubSelect wird zuerst ausgeführt, welche Join Methode wird verwendet etc...
Anhand eines solchen Execution Plans sollte eigentlich jedes Statement einer Applikation optimiert werden, allein das kann bei komplexen Anwendungen mehrere 100! % Performancegewinn bringen ohne auch nur einen Parameter der Datenbank zu tunen.