Mysql
 sql >> Datenbank >  >> RDS >> Mysql

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

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

Profi-Tipp:Niemals Verwenden Sie SELECT * in Software, es sei denn, Sie wissen absolut, warum Sie es tun. Besonders bei Abfragen, die viel JOIN enthalten Operationen, SELECT * gibt viele sinnlose und redundante Spalten zurück.

Für das postmeta von WordPress gibt es einen Query-Design-Trick, den man kennen sollte Tisch. Wenn Sie ein bestimmtes Attribut erhalten möchten, tun Sie dies:

 SELECT p.ID, p.post_title,
        color.meta_value AS color
   FROM wp_posts AS p
   LEFT JOIN wp_postmeta AS color ON p.ID = color.post_id AND 'color' = color.meta_key
  WHERE p.post_status = 'publish'
    AND /* etc etc */

Es ist äußerst wichtig, dieses Muster zu verstehen, wenn Sie das tun, was Sie tun möchten. Dieses Muster ist erforderlich, weil postmeta ist ein besonderer Tabellentyp, der als bezeichnet wird oder Geschäft. Was ist denn hier los? Ein paar Dinge:

  1. Wenn Sie dieses Muster verwenden, erhalten Sie eine Zeile für jeden Beitrag mit einigen Spalten aus den posts Tabelle und ein bestimmtes Attribut aus dem postmeta Tabelle.
  2. Sie sind LEFT JOIN das postmeta verwenden Tabelle, sodass Sie immer noch eine Zeile erhalten, wenn das Attribut fehlt.
  3. Sie verwenden einen Aliasnamen für die postmeta Tisch. Hier ist es postmeta AS color .
  4. Sie schließen den Selektor für meta_key ein (hier ist es 'color' = color.meta_key ) im ON Zustand des Joins.
  5. Sie verwenden einen Alias ​​in Ihrem SELECT -Klausel, um den postmeta.meta_value darzustellen Element mit einem entsprechenden Spaltennamen. Hier ist es 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 stapeln Operationen, um viele verschiedene Attribute zu erhalten, so.

     SELECT wp_posts.ID, wp_posts.post_title, wp_posts.whatever,
            color.meta_value        AS color,
            transmission.meta_value AS transmission,
            model.meta_value        AS model,
            brand.meta_value        AS brand
       FROM wp_posts

  LEFT JOIN wp_postmeta  AS color 
         ON wp_posts.ID = color.post_id        AND color.meta_key='color'

  LEFT JOIN wp_postmeta  AS transmission
         ON wp_posts.ID = transmission.post_id AND transmission.meta_key='transmission'

  LEFT JOIN wp_postmeta  AS model
         ON wp_posts.ID = model.post_id        AND model.meta_key='model'

  LEFT JOIN wp_postmeta  AS  brand
         ON wp_posts.ID = brand.post_id        AND brand.meta_key='brand'

      WHERE wp_posts.post_status = 'publish'
        AND wp_posts.post_type = 'car'
   ORDER BY wp_posts.post_title

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

Es ist schwer zu sagen, warum Sie Leistungsprobleme mit der Abfrage in Ihrer Frage hatten. Es liegt möglicherweise daran, dass Sie mit all den INNER JOIN eine kombinatorische Explosion erhalten haben Operationen, die dann gefiltert wurden. Aber auf jeden Fall hat die von Ihnen gezeigte Abfrage wahrscheinlich keine Zeilen zurückgegeben.

Wenn Sie immer noch Leistungsprobleme haben, versuchen Sie, einen zusammengesetzten Index auf postmeta zu erstellen auf dem (post_id, meta_key, meta_value) Säulen. Wenn Sie ein WordPress-Plugin erstellen, ist dies wahrscheinlich eine Aufgabe, die Sie während der Installation des Plugins erledigen müssen.