Eine Abfrage mit vielen inneren Verknüpfungen zu wp_postmeta, einer Schlüssel / Wert-Tabelle, verbessern

8

arbeite mit einer Wordpress-Website, die die folgende Abfrage ausführt, aber ich sehe, dass diese Abfrage viele innere Joins ausführt und die Website lange braucht, um geladen zu werden, und viel herunterkommt, und ich habe versucht, eine Abfrage zu erstellen, die produziert das gleiche Ergebnis, aber noch ohne Erfolg

Ich würde gerne wissen, was könnte ein besserer Weg, dies zu tun

%Vor%

Hier ist die EXPLAIN-Ausgabe.

%Vor%

Wordpress-Schema hier.

    
Juan Jo 11.10.2014, 21:50
quelle

8 Antworten

10

Es scheint, dass Sie versuchen, eine Ergebnismenge mit einer Zeile pro Beitrag vom Typ car zu erhalten. Es scheint, dass Sie verschiedene Attribute jedes Autos in der Post anzeigen möchten, und diese sind in postmeta verstaut.

Pro-Tipp: Nie verwenden Sie SELECT * in der Software, es sei denn, Sie wissen absolut, warum Sie es tun. Insbesondere bei Abfragen, die viele JOIN -Operationen enthalten, gibt SELECT * viele sinnlose und redundante Spalten zurück.

Es gibt einen Abfrage-Design-Trick für die WordPress postmeta -Tabelle. Wenn Sie ein bestimmtes Attribut erhalten möchten, tun Sie dies:

%Vor%

Es ist sehr wichtig, dieses Muster zu verstehen, wenn man das tut, was man versucht. Dieses Muster ist erforderlich, weil postmeta ein spezieller Tabellentyp ist, der als Schlüssel / Wert-Speicher bezeichnet wird. Was ist denn hier los? Ein paar Dinge:

  1. Unter Verwendung dieses Musters erhalten Sie für jeden Post eine Zeile mit einigen Spalten aus der Tabelle posts und einem bestimmten Attribut aus der Tabelle postmeta .
  2. Sie sind LEFT JOIN in der Tabelle postmeta , so dass Sie immer noch eine Zeile erhalten, wenn das Attribut fehlt.
  3. Sie verwenden einen Aliasnamen für die Tabelle postmeta . Hier ist postmeta AS color .
  4. Sie fügen den Selektor für meta_key (hier ist es 'color' = color.meta_key ) in die ON -Zustand des Joins ein.
  5. Sie verwenden in Ihrer SELECT -Klausel einen Alias, um das Element postmeta.meta_value mit einem geeigneten Spaltennamen darzustellen. Hier ist color.meta_value AS color .

Sobald Sie sich daran gewöhnt haben, dieses Muster zu verwenden, können Sie es mit einer Kaskade von LEFT JOIN -Operationen stapeln, um so viele verschiedene Attribute zu erhalten.

%Vor%

Ich habe bei dieser Abfrage eine Reihe von Einrückungen vorgenommen, um das Muster leichter zu erkennen. Möglicherweise bevorzugen Sie einen anderen Einzugsstil.

Es ist schwer zu wissen, warum Sie Leistungsprobleme mit der Abfrage in Ihrer Frage hatten. Das liegt möglicherweise daran, dass Sie eine kombinatorische Explosion mit allen INNER JOIN -Operationen erhalten haben, die dann gefiltert wurden. Aber auf jeden Fall gab die Abfrage, die Sie zeigten, wahrscheinlich keine Reihen zurück.

Wenn Sie immer noch Leistungsprobleme haben, erstellen Sie einen zusammengesetzten Index für postmeta in den Spalten (post_id, meta_key, meta_value) . Wenn Sie ein WordPress-Plugin erstellen, ist das wahrscheinlich eine Aufgabe, die Sie bei der Installation des Plugins erledigen müssen.

    
O. Jones 14.10.2014, 14:33
quelle
2

Dies ist eine Wordpress-Datenbank, und Sie werden möglicherweise nur ungern umfangreiche Änderungen am Schema vornehmen, da dies in der Zukunft andere Teile der Anwendung beschädigen oder Upgrades verkomplizieren könnte.

Die Schwierigkeit dieser Abfrage zeigt eine der Schattenseiten der Design. Dieses Design ist insofern flexibel, als es erlaubt, neue Attribute zur Laufzeit zu erzeugen, aber es macht eine Menge von Abfragen gegen solche Daten komplexer, als dies bei einer herkömmlichen Tabelle der Fall wäre.

Das Schema für Wordpress wurde nicht gut optimiert. Es gibt einige naive Indexierungsfehler, sogar in der aktuellsten Version 4.0.

Für diese bestimmte Abfrage helfen die folgenden zwei Indizes:

%Vor%

Der bk1 Index hilft dabei, genau den richtigen Metaschlüssel und Wert zu finden.

Der bk2 Index hilft dabei, den Filesort zu vermeiden.

Diese Indizes können keine Indizes abdecken, da post_title und meta_value TEXT Spalten sind und diese zu lang sind, um vollständig indiziert zu werden. Sie müssten sie in VARCHAR(255) ändern. Das birgt jedoch die Gefahr, dass die Anwendung beschädigt wird, wenn sie längere Strings in dieser Tabelle speichert.

%Vor%     
Bill Karwin 14.10.2014 15:14
quelle
2

Um das Leistungsproblem mit 10+ Joins SQL-Abfragen in innodb-Tabellen mit utf8-Zeichensatz zu lösen, erstellen Sie einen neuen Index für postmeta:

Datenbank zuerst sichern. Reduzieren Sie [wp_]postmeta.meta_key length auf 191, um zu vermeiden, dass " Angegebener Schlüssel zu lang war; maximale Schlüssellänge ist 767 Byte " Fehler.

ALTER TABLE wp_postmeta MODIFY meta_key VARCHAR(191);

Index erstellen

CREATE INDEX wpm_ix ON wp_postmeta (post_id, meta_key);

    
sglessard 18.07.2017 14:21
quelle
0

Für die Leistung versuchen Sie:

Geben Sie explizit die Spalten an, die Sie ziehen möchten. Sehen Sie, welche Indizes Sie benötigen oder nicht. Begrenzen Sie die Anzahl der gezogenen Zeilen.

    
RoganRicheart 12.10.2014 00:09
quelle
0

ist das besser?

%Vor%

Wenn es immer noch langsam ist, was wahrscheinlich der Fall ist, versuchen Sie, diesen Index hinzuzufügen,

%Vor%

Sie könnten auch versuchen, diesen Index zu wp_post

hinzuzufügen %Vor%

Je mehr Sie die Auswahlliste einschränken können (das Bit zwischen SELECT und FROM ), desto besser. Es hat keinen Sinn, viele Daten zurückzugeben, die Sie nicht verwenden. Sie erhalten die beste Leistung, wenn die gesamte Auswahlliste von einem Index "abgedeckt" ist.

    
Jodrell 14.10.2014 15:11
quelle
0

Angenommen, Sie können den Code ändern, der die Ergebnisse verarbeitet, würde ich eine viel einfachere Abfrage erstellen und den Code verwenden, um die Ergebnisse zu filtern.

%Vor%

Oder Sie könnten etwas wie ...

tun %Vor%     
Uueerdo 16.10.2014 17:45
quelle
0

In WordPress gibt es ein gutes Abfrage-Tool namens WP_Query. Um in Post-Meta-Werten zu suchen, können Sie diesen Code verwenden:

%Vor%

Weitere Informationen zur Abfrage-API finden Sie auf dieser Website. Es gibt zahlreiche Beispiele: Ссылка

    
xrissz 26.10.2014 11:28
quelle
0

Die Beschleunigung von wp_postmeta finden Sie hier: Ссылка

Und Warum sind Verweise auf wp_postmeta so langsam?

    
Rick James 24.07.2017 04:29
quelle