sql >> Database >  >> RDS >> Mysql

Een query verbeteren met veel inner joins naar wp_postmeta, een sleutel/waarde-tabel

Het lijkt erop dat je een resultatenset probeert te verkrijgen met één rij per post van het type car . Het lijkt erop dat je verschillende attributen van elke auto in de post wilt weergeven, en die zijn opgeborgen in postmeta .

Pro-tip:Nooit gebruik SELECT * in software, tenzij je absoluut weet waarom je het doet. Vooral bij zoekopdrachten met veel JOIN bewerkingen, SELECT * geeft veel zinloze en overbodige kolommen terug.

Er is een truc voor het ontwerpen van query's voor de WordPress postmeta tafel. Als u een bepaald kenmerk wilt krijgen, doet u dit:

 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 */

Het is superbelangrijk om dit patroon te begrijpen wanneer je doet wat je probeert te doen. Dit patroon is vereist omdat postmeta is een eigenaardig type tabel genaamd een of op te slaan. Wat is hier aan de hand? Een paar dingen:

  1. Als je dit patroon gebruikt, krijg je één rij voor elke post, met enkele kolommen uit de posts tabel en een bepaald attribuut uit de postmeta tafel.
  2. Je bent LEFT JOIN de postmeta tabel zodat u nog steeds een rij krijgt als het kenmerk ontbreekt.
  3. Je gebruikt een aliasnaam voor de postmeta tafel. Hier is het postmeta AS color .
  4. Je neemt de selector op voor meta_key (hier is het 'color' = color.meta_key ) in de ON staat van de join.
  5. Je gebruikt een alias in je SELECT clausule om de postmeta.meta_value . te presenteren item met de juiste kolomnaam. Hier is het color.meta_value AS color .

Als je eenmaal gewend bent aan het gebruik van dit patroon, kun je het opstapelen met een cascade van LEFT JOIN bewerkingen, om veel verschillende attributen te krijgen, zoals zo.

     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

Ik heb een heleboel inspringen op deze query gedaan om het patroon gemakkelijker te kunnen zien. Misschien geeft u de voorkeur aan een andere inspringstijl.

Het is moeilijk te achterhalen waarom u prestatieproblemen had met de query in uw vraag. Het is mogelijk dat je een combinatorische explosie kreeg met alle INNER JOIN bewerkingen die vervolgens werden gefilterd. Maar in ieder geval leverde de zoekopdracht die je liet zien waarschijnlijk geen rijen op.

Als je nog steeds prestatieproblemen hebt, probeer dan een samengestelde index te maken op postmeta op de (post_id, meta_key, meta_value) kolommen. Als je een WordPress-plug-in maakt, is dat waarschijnlijk een taak die je moet doen tijdens de installatie van de plug-in.



  1. MariaDB JSON_ARRAY_INSERT() uitgelegd

  2. Een HTML-e-mail verzenden vanuit SQL Server (T-SQL)

  3. Kun je een For Each Row-lus maken met MySQL?

  4. Hoe alias een veld of kolom in MySQL?