Hier ist eine Frage, die ich gestern gestellt habe - /programming/22180727/left-joining-two-views-is-slow .
Ich habe eine gute Antwort erhalten, die mir geholfen hat, aber ich verstehe nicht, warum der LEFT JOIN so viel langsamer ist als die Suche. Der LEFT JOIN betrug 16 Sekunden - und ich bin mir ziemlich sicher, dass meine Tabellen zu mindestens 90% optimiert sind - und bei der Suche sind es nur 0,14 Sekunden. Wenn ich JOIN-Tabellen verlassen habe, ist es nicht so langsam. Warum also Ansichten?
Antworten:
Gemäß der MySQL-Dokumentation zu Ansichten
Das erste, was an einer Ansicht erkannt werden muss, ist, dass sie eine Ergebnismenge erzeugt. Die Ergebnismenge, die aus der in der Ansicht aufgerufenen Abfrage hervorgeht, ist eine virtuelle Tabelle, da sie bei Bedarf erstellt wird. Es gibt keine DDL, die Sie anschließend aufrufen können, um die Ergebnismenge sofort zu indizieren. Die Ergebnismenge ist in jeder Hinsicht eine Tabelle ohne Indizes. Tatsächlich handelt es sich bei dem von Ihnen ausgeführten LEFT JOIN im Grunde genommen um ein kartesisches Produkt mit einigen Filtern.
Um Ihnen einen genaueren Überblick über die Verbindung zweier Ansichten zu geben, verweise ich auf einen Beitrag, den ich im letzten Jahr verfasst habe, in dem die internen Mechanismen erläutert werden, mit denen MySQL JOINs und WHEREs bewertet ( Gibt es einen Ausführungsunterschied zwischen einer JOIN-Bedingung und einer WHERE-Bedingung? ). Ich werde Ihnen den Mechanismus zeigen, wie er in Understanding MySQL Internals (Seite 172) veröffentlicht wurde:
ORDER BY
und verwendet werden könnenGROUP BY
.OK, es scheint, als sollten Indizes verwendet werden. Schauen Sie jedoch genauer hin. Wenn Sie das Wort
View
durch ersetzenTable
, schauen Sie, was mit der Ausführung des Mechanismus passiert:MECHANISMUS GEÄNDERT
views
, und wählen Sie jeweils den besten ausview
.view
Entscheiden Sie für jeden , ob einview
Scan besser ist als das Lesen auf einem Schlüssel. Wenn viele Datensätze mit dem Schlüsselwert übereinstimmen, werden die Vorteile des Schlüssels verringert und derview
Scanvorgang wird schneller.views
soll, wenn mehr als eineviews
in der Abfrage vorhanden ist.views
aus dem Join.ORDER BY
und verwendet werden könnenGROUP BY
.Jede Tabelle (Ansicht) hat keinen Index. Daher wird die Arbeit mit virtuellen Tabellen, temporären Tabellen oder Tabellen ohne Indizes beim Ausführen eines JOIN wirklich undeutlich. Die verwendeten Schlüssel sind nur für JOIN-Operationen gedacht, nicht so sehr für das schnellere Nachschlagen.
Stellen Sie sich Ihre Anfrage so vor, als würden Sie zwei Telefonbücher abholen, die Gelben Seiten 2014 und die Gelben Seiten 2013. Jedes Buch mit den Gelben Seiten enthält die Weißen Seiten für Telefonnummern für Privathaushalte.
Offensichtlich gibt es Unterschiede zwischen den beiden Telefonbüchern. Das Zusammenführen von Datenbanktabellen, um die Unterschiede zwischen 2013 und 2014 herauszufinden, sollte kein Problem darstellen.
Stellen Sie sich vor, Sie führen die beiden Telefonbücher von Hand zusammen, um Unterschiede zu lokalisieren. Klingt verrückt, nicht wahr? Ungeachtet dessen ist es genau das, was Sie von mysqld verlangen, wenn Sie zwei Ansichten verbinden. Denken Sie daran, dass Sie keine echten Tabellen verbinden und es keine Indizes gibt, aus denen Sie Huckepack nehmen können.
Lassen Sie uns nun auf die eigentliche Abfrage zurückblicken.
Sie verwenden eine virtuelle Tabelle (Tabelle ohne Indizes), viewA, und verbinden sie mit einer anderen virtuellen Tabelle, viewB. Die temporäre Tabelle, die intermittierend generiert wird, ist so groß wie viewA. Anschließend führen Sie eine interne Sortierung für die große temporäre Tabelle aus, um sie zu unterscheiden.
EPILOG
Angesichts der internen Mechanismen zur Auswertung von JOINs sollte Ihre ursprüngliche Abfrage (LEFT JOIN aus zwei Ansichten) Laufzeiten in Größenordnungen erhalten, da die Ergebnismenge einer Ansicht vorübergehend und indexlos ist. Gleichzeitig sollte die Antwort , die Sie von StackOverflow erhalten haben , angesichts des gleichen JOIN-Algorithmus, den ich gerade beschrieben habe, gut funktionieren.
Ich hoffe, die blutigen Details, die ich gerade gepostet habe, beantworten Ihre Frage, warum.
quelle
EXPLAIN EXTENDED [select query]
und zeigt dannSHOW WARNINGS
die umgeschriebene Form der Ansicht an. Von hier aus ist es einfacher, Leistungsmerkmale zu analysieren.Abfragen zur Sichtprüfung sind im Allgemeinen nicht einfach zu optimieren.
quelle
Die Antwort hat mit der Methode zur Durchführung jeder dieser Operationen zu tun.
Da Ansichten von Natur aus nicht indiziert sind, dauern JOIN-Vorgänge mit Feldern aus Ansichten länger als JOIN-Vorgänge mit Tabellen, da der Scan keinen Index verwenden kann.
In diesem Fall begrenzt die Suche auch die Anzahl der Datensätze, die bei der Verarbeitung zurückgegeben werden müssen. Es werden nur Datensätze aus einer Ansicht abgerufen, die in der anderen nicht vorhanden sind. Der JOIN zieht alle Datensätze und prüft dann, ob in beiden Datensätzen vorhanden sind.
quelle
MERGE
Algorithmus zum Verarbeiten der Ansicht verwendet werden kann, können und werden die Indizes für die zugrunde liegenden Tabellen verwendet. Nur wenn die Ansichtsdefinition denTEMPTABLE
Algorithmus explizit verwendet oder die Ansicht Funktionen enthält, die implizit eine temporäre Tabelle erfordern, werden die Ansichtsergebnisse in einer temporären Tabelle materialisiert. dev.mysql.com/doc/refman/5.6/en/view-algorithms.html