Hallo, Jimmy -
wieder so eine "esoterische" Frage
Es gibt verschiedene Gründe.
1. ein PRIMARY KEY erzwingt einen Index, da der Server sonst nicht prüfen kann, ob bei der Anlage eines Satzes eine Verletzung des PRIMARY KEY CONSTRAINTS auftritt;
2. zur Suchoptimierung
Das Thema Suchoptimierung ist etwas umfangreicher, und ich kann es hier nur in grundsätzlichen Zügen anreissen.
Wenn Du mit einer Tabelle arbeitest, die tausend Datensätze hast, kannst Du das Thema Index eigentlich knicken, da jeder SQL Server schnell genug sein sollte, hier jede Sortierung im Handumdrehen zur Verfügung zu stellen. Reden wir über eine Million Datensätze, sieht das Thema anders aus, dann kann der SELECT ... ORDER BY schon ordentlich dauern. Manche SQL Server dokumentieren das auch, indem sie im Log einen Hinweis hinterlassen, dass ein Index (!) erstellt wurde. Dieser Index ist aber temporär und wird danach "entsorgt".
Jetzt kommen wir zum "Grundsätzlichen", denn jeder SQL-Server verhält sich hier anders. Der eine Server mag den Index zwar temporär anlegen, hält ihn aber so lange am Leben, wie Deine Session dauert und aktualisiert ihn auch in dieser Zeit, ein anderer Server kann den temporären Index sofort löschen, nachdem der SELECT Befehl abgearbeitet ist. Meine Ausführungen gelten für das grundsätzliche Verhalten, wie sich PostgreSQL oder MySQL verhält, hängt immer von der Implementierung ab.
Wenn Du also weisst, dass Deine Anwender eine bestimmte Suchreihenfolge bevorzugen, ist es sinnvoll, hierfür einen Index anzulegen, da durch einen solchen Index die SELECT Anweisungen deutlich schneller abgearbeitet werden als ohne.
Query-Optimizer - das ist jetzt ganz "esoterisch". Ich komme halt mal wieder auf die IBM iSeries (oder heisst sie jetzt i5?) zurück. Dort arbeitet ein richtig geiler Query-Optimizer, der alle vorhandenen Index-Dateien überprüft und die verwendet, die der Suchabfrage am ehesten entsprechen. Das könnte so aussehen:
Du hast ein
Code: Alles auswählen
SELECT * FROM kunden WHERE KName = 'Müller' AND KGeboren = '1977-06-13'
Es gibt einen Index über KName, KVorname - dann nimmt ein guter Optimizer diesen Index, sucht dort alle 'Müller' raus und jagt die Abfrage nach dem Geburtsdatum über dieses Subset, was natürlich rasend schnell ist (es sei denn, es gibt zwei Millionen 'Müller' in der Tabelle). Gibt es noch einen Index über das Geburtsdatum, würde ein richtig guter Optimizer prüfen, bei welchem Index weniger Zeilen rauskommen, diesen Index verwenden und dann die zweite Abfrage über das Subset jagen.
Aber das ist alles abhängig von der Implementierung des jeweiligen Servers, und es kann auch schon vom Betriebssystem des Servers abhängen, was geht und was nicht.
Jetzt schaue ich in meine Glaskugel und sehe Deine nächste Frage: "Soll ich dann einen Index über jedes Feld legen?" Die Antwort lautet: "Am besten nicht", denn jeder Index muss gepflegt werden, und das kann zu Verzögerungen führen. Bei richtig grossen Tabellen würde ich über die Felder, die voraussichtlich als Suchkriterium dienen, einen Index legen.
Beispiel (ich weiss, ich schweife ab, aber was solls, das tun andere auch): MySQL auf Linux ist case sensitive. meineTabelle <> meinetabelle <> MEINETABELLE. Unter Windows wäre diese drei Tabellen- (oder Datenbank-)namen identisch. Grund: MySQL legt für jede Database ein Verzeichnis an, und für jede Tabelle eine Datei. Da diese unter Linux (normalerweise) auf einem Dateisystem abgelegt werden, das case sensitive ist, schlägt ein
fehl, wenn die Tabelle mit
angelegt wurde.
Leider sind diese Hinweise oft sehr tief im Handbuch versteckt, und man wundert sich, warum die Anwendung auf dem heimischen PC (SQL Server unter Windows) beim Kunden nicht läuft, obwohl der die gleiche Version des Servers auf Linux (oder Mac OS) einsetzt.
Gruss,
Georg