2011-01-07 3 views
2

Ich bin hier ziemlich ratlos.Index auf einer Tabelle müssen Sie trotzdem vollständig scannen? (MySQL)

Ich habe 2 Tabellen und ich verbinde die erste (etwa 500k Datensätze) mit der zweiten (etwa 2,2 Millionen Datensätze), um herauszufinden, welche Datensätze in der ersten und nicht in der zweiten sind. (typisch "b.attribute is null" Unsinn)

Warum (wie) ist es, dass ein Index auf der ersten Tabelle verwendet wird? Es wird sowieso jeden Datensatz in der ersten Tabelle durchlaufen müssen, und wenn ich versuche, diese Verknüpfung ohne einen Index (oder Primärschlüssel ... keiner benötigt, weil dies alles nur ETL ist) in der ersten Tabelle zu machen, kriecht es.

mit innodb, übrigens.

Hilfe?

EDIT: Die zweite Tabelle ist indiziert. Der erste war nicht.

Antwort

1

Ich habe keine Ahnung, ob das ist, was passiert, aber es wäre theoretisch möglich (je nach der tatsächlichen Abfrage) für die Datenbank-Engine den Index für die linke Tabelle statt die Tabelle selbst zu scannen. Es könnte die notwendigen Schlüsseldaten dafür aufbauen. Wenn das Scannen des Index schneller als das Scannen der Tabelle war, könnte dies für die Geschwindigkeitsdifferenz verantwortlich sein.

+0

Beschreiben sagt mir, dass es beide Indizes der Tabelle verwendet. Vielleicht bringt es den Index in Erinnerung statt viel von der Tabelle? Ich bin mir nicht sicher, wie diese Situation gehandhabt wird. daher die Frage. –

+0

@brian, das ist sicherlich möglich. Ein vollständig sequentielles Lesen einer Datei kann extrem schnell sein. Wenn also der Index in zusammenhängendem Speicherplatz auf der Festplatte wäre und nicht zu groß wäre, wäre es sinnvoll, ihn in den Speicher einzulesen. –

+0

In der Tat. Ich sollte beachten, dass NOTHING auf der ersten Tabelle indexiert wurde (kein pk), bevor ich merkte, dass ein Index es viel schneller machte. IE: keine Möglichkeit, etwas über diese Tabelle im zusammenhängenden Speicher zu haben, die leicht in RAM passen würde.Trotzdem würde ich eine konkretere Antwort bevorzugen, wenn jemand in –

0

MySQL hat keine Hash-Joins.

1

Der Zweck des primären Index ist es, die Dinge in Ordnung zu bringen, indem man einen großen Baum sortiert und erstellt (zumindest in SQL Server). B-Baum, um genauer zu sein. Dies bedeutet, dass der Schlüssel jedes Datensatzes zu einem bestimmten Ort (oder Bucket) in der Struktur gehört.

alt text

Warum Hinzufügen eines Schlüssels zu der ersten Tabelle hilft, die Abfrage zu beschleunigen? Der Grund dafür ist, dass die FIRST-Tabelle beim Ausführen der Abfrage sortiert ist, da die Tabelle SECOND aufgrund des Vorhandenseins eines Primärschlüssels bereits ist. Dies liegt an der einfachen Tatsache, dass das Vergleichen von zwei sortierten Listen viel schneller ist als das Ausführen einer binären Suche für jedes Element. In diesem Fall dauert das Sortieren Zeit, da kein Index vorhanden ist.

Übrigens, nicht durch das, was ich sage, verwirrt sein. Es ist nicht wirklich Listen zu vergleichen, sondern mehr den Indexbaum auf dem obigen Bild zu beschneiden, z. Wenn der T1 K1, K2, K3 und K1 im zweiten Bucket auf dem Bild gefunden hat, ist es nicht nötig, den ersten Bucket für den Rest der Schlüssel zu überprüfen.

+0

AH Mist, ich danke Ihnen für Ihre Mühe, aber meine Frage bezieht sich auf das Fehlen von Indizes auf der ersten Tabelle nur. In Ihrem Beispiel sind Sie immer noch an den vollständigen Scan (500k) der ersten Tabelle gebunden, der eindeutig meine Frage nicht beantwortet, wie ein Index eine Geschwindigkeitsverbesserung für eine Tabelle liefert, deren Datensätze sowieso ausgewertet werden müssen. –

+0

@brian: oh, richtig. mein Fehler. – Schultz9999

+0

@brian: bearbeitet, um es auf den Punkt zu bringen. – Schultz9999

2

Dies sollte etwas Licht auf sie wirft: http://dev.mysql.com/doc/refman/5.5/en/innodb-index-types.html

Kurz gesagt: Alle InnoDB-Tabellen sind so ‚Clustered-Index‘ genannt (auch wenn kein expliziter Index für die Tabelle definiert ist, InnoDB schafft es automatisch), in dem Die tatsächlichen Zeilen werden gespeichert.

+0

Ich sehe nur nicht, wo eine Geschwindigkeitsverbesserung durch Hinzufügen von regulären Indizes kommen würde (obwohl dieser Artikel sehr informativ war). Mein einziger Gedanke ist jetzt, dass die erste Tabelle immer die Tabelle war, die durchsucht wurde, im Gegensatz zu vollständig gescannt, und es macht es jetzt in Log-Zeit für jeden Eintrag jetzt. Das ist alles, was ich mir vorstellen kann. Sicher würde der neue Index, den ich erstellt habe, nicht verwendet werden, wenn er überflüssig wäre? Und es ist einfach genug, während ETL zu deaktivieren. Aber ich verstehe immer noch nicht ... –

+0

TBH ich auch nicht. InnoDB ist nicht so intuitiv wie es auf den ersten Blick scheinen mag. Außerdem könnte der Optimierer tatsächlich einen Index verwenden, selbst wenn er nicht benötigt wird, oder sogar schlimmer, verlangsamt die Dinge. Es kann gelegentlich nicht den besten Ausführungsplan für Ihre Abfrage auswählen. Deshalb gibt es Mittel, die Indexnutzung zu erzwingen. – Mchl

Verwandte Themen