Was bedeutet "Index" für RDBMS? [geschlossen]


21

Ich verwende Indizes wie die meisten Entwickler (hauptsächlich bei ... well! Index), aber ich bin mir sicher, dass es viele subtile Möglichkeiten gibt, eine Datenbank mithilfe von index zu optimieren. Ich bin nicht sicher, ob es spezifisch für eine Implementierung eines DBMS ist.

Meine Frage lautet: Was sind gute Beispiele für die Verwendung des Index (außer in einfachen, offensichtlichen Fällen), und wie optimiert ein DBMS seine Datenbank, wenn Sie einen Index für eine Tabelle angeben?


Bei der weiteren Betrachtung dieser Frage ist diese Frage für diese Site zu allgemein. Wenn wir den Gültigkeitsbereich der Frage ändern, ist diese Frage ansonsten für die Site nicht geeignet.
Jcolebrand

Ich erkläre gerne Indizes mithilfe der Bibliotheksmetapher mysqlperformanceblog.com/2011/08/30/…. Sehen Sie, ob das hilft.
Jonathan

Antworten:


11

Stellen Sie sich einen Index als "Inhaltsverzeichnis" vor. Dies ist eine geordnete Liste von Zeigern auf Positionen in einer Datei, auch Offsets genannt. Angenommen, Sie haben Millionen von Datensätzen in einer Tabelle gespeichert, anstatt in der Tabelle nach Übereinstimmungskriterien zu suchen. Es ist viel schneller, auf eine geordnete Liste für Übereinstimmungen zu verweisen und dann die Zeiger auf die spezifischen übereinstimmenden Zeilen zu stapeln. Ein perfektes Beispiel für einen Index ist ein Tabellen-Primärschlüsselfeld, in der Regel das Feld "id". Wenn Sie die Zeilen-ID # 11234566 möchten, können Sie den Index viel schneller nach einem Zeiger auf die Daten fragen, als wenn Sie die Datenquelle nach Position 11234566 durchsuchen.

Hier ist eine nicht so offensichtliche Verwendung der Indizierung:

CREATE TABLE activity_log (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
activity_type_id SMALLINT UNSIGNED NOT NULL,
datetime_created DATETIME
KEY(activity_type_id),
PRIMARY KEY(id)
);
CREATE TABLE activity_log_to_date_key (
activity_log_id INT UNSIGNED NOT NULL,
date_created_key  INT UNSIGNED NOT NULL REFERENCES dim_datetime(id),
UNIQUE KEY(activity_log_id),
KEY(date_created_key)
);
CREATE TABLE dim_datetime (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
date_hour DATETIME NOT NULL,
PRIMARY KEY(id),
KEY(date_hour)
);

Ihre Operation kann Ihren Protokolldatensatz erstellen, erstellt dann jedoch einen Verweis auf eine indizierte Datumszeit, die schneller durchsucht / sortiert werden kann als Ihre Protokolltabelle. Verbinden Sie dann Ihre Protokolltabelle mit einem eigenen Primärschlüssel. Wenn Sie mich brauchen, um dies zu erweitern, lassen Sie es mich wissen. Ich hoffe das macht Sinn.

Beispielabfrage:

SELECT a.activity_log_id, al.activity_type_id, al.datetime_created
FROM activity_log_to_date_key a 
INNER JOIN dim_datetime d ON (d.id = a.date_created_key)
LEFT JOIN activity_log al ON (al.id = a.activity_log_id)
WHERE d.date_hour BETWEEN '2009-01-01 00:00:00' AND '2009-06-01 12:00:00';

danke, das ist sehr klar! Wird "PRIMARY" in Ihrem Beispiel die Art und Weise ändern, in der der RDMBS den "Offset" speichert, oder wird er nur für Eindeutigkeitsbeschränkungen verwendet?
Thomas Joulin

9

Ein Punkt, den viele Leute vermissen, ist, dass ein DBMS häufig (oder nur) einen Index pro Tabellenreferenz in einer Abfrage verwendet. Wenn es mehrere Indizes verwenden kann und tut, wäre es wahrscheinlich schneller, einen kombinierten Index zu verwenden Index falls vorhanden.

Wenn Sie beispielsweise eine große Tabelle nach Zeilen durchsuchen, ist WHERE AnIntegerColumn = 42 AND AnOtherInt = 69der schnellste Weg zu diesen Zeilen ein Index für die beiden Spalten AnIntegerColumn und AnOtherInt. Wenn Sie nur einen Index für jeden einzelnen, aber keinen kombinierten Index haben, durchsucht die DB entweder den einen oder den anderen Index und filtert die Ergebnisse separat mit der zweiten Klausel oder scannt beide und heiratet die Ergebnisse anschließend.

Eine weitere übliche einfache Operation, die mit zusammengesetzten Indizes verbessert werden kann, ist WHERE SomeColumn = <SomeValue> ORDER BY SomeOtherColumn: Wenn für SomeColumn und SomeOtherColumn ein Index vorhanden ist (in der richtigen Reihenfolge), können die Filter- und Ordnungsoperationen unter bestimmten Umständen gleichzeitig ausgeführt werden.

Das Hinzufügen zu vieler Indizes kann natürlich eine schlechte Optimierung sein, da der zusätzliche Speicherplatz zum Speichern der Indizes (und die E / A-Last, um sie zu verwalten, wenn Ihre DB viele Schreibvorgänge sieht) möglicherweise ein schlimmeres Problem darstellt als die etwas weniger optimalen Leseabfragen Also übertreib es nicht.


2

David und Randy haben dies abgedeckt. Ich wollte nur hinzufügen, dass der EXPLAINBefehl eine große Hilfe sein kann, um herauszufinden, wann Sie große Einsparungen beim Erstellen eines Index erzielen und welche Indizes benötigt werden. Es werden die Schritte angezeigt, die die Datenbank ausführt, um Ihre Abfrage auszuführen, damit Sie wissen, welche Bits die längste Zeit in Anspruch nehmen.


Um die Antwort von Gaurav zu ergänzen, verwenden Sie "EXPLAIN EXTENDED" und geben Sie dann sofort "SHOW WARNINGS" ein, um zu sehen, wie Ihre Abfrage übersetzt wird.
Randomx

1

Was ich hier noch nicht erwähnt habe, ist, dass Sie, wenn Sie mehr als eine Festplatte haben, Ihren Index wahrscheinlich auf einer anderen Festplatte ablegen möchten, als dort, wo sich die Daten tatsächlich befinden. Dies kann einige Vorgänge beschleunigen. Ich denke, das verdient eine eigene Frage.


Früher stimmte das, aber heutzutage versuchen Sie nicht, Ihr E / A-Subsystem zu überdenken. Sie wissen ohnehin nicht, wo ein Speicherarray Ihre Daten ablegen wird.
Gaius

1
@gaius Ich meinte eher, wenn Sie kein RAID5-Setup (oder ähnliches) hatten, um die Indizes auf E :, die Daten auf F: usw. zu setzen.
jcolebrand
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.