Mysql
 sql >> Database >  >> RDS >> Mysql

Miglioramento di una query utilizzando molti inner join a wp_postmeta, una tabella chiave/valore

Sembra che tu stia cercando di ottenere un set di risultati con una riga per post di tipo car . Sembra che tu voglia visualizzare vari attributi di ogni auto nel post e quelli sono nascosti in postmeta .

Suggerimento per professionisti:Mai usa SELECT * nel software a meno che tu non sappia assolutamente perché lo stai facendo. Soprattutto con query contenenti molti JOIN operazioni, SELECT * restituisce molte colonne inutili e ridondanti.

C'è un trucco per la progettazione delle query da conoscere per il postmeta di WordPress tavolo. Se vuoi ottenere un attributo particolare, procedi come segue:

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

È estremamente importante comprendere questo schema quando fai ciò che stai cercando di fare. Questo modello è obbligatorio perché postmeta è un tipo particolare di tabella chiamata o negozio. Cosa sta succedendo qui? Alcune cose:

  1. Utilizzando questo schema ottieni una riga per ogni post, con alcune colonne dai posts tabella e un particolare attributo dal postmeta tabella.
  2. Sei LEFT JOIN nel postmeta tabella in modo da ottenere comunque una riga se manca l'attributo.
  3. Stai usando un nome alias per postmeta tavolo. Ecco postmeta AS color .
  4. Stai includendo il selettore per meta_key (qui è 'color' = color.meta_key ) nel ON condizione dell'unione.
  5. Stai usando un alias nel tuo SELECT clausola per presentare il postmeta.meta_value elemento con un nome di colonna appropriato. Ecco color.meta_value AS color .

Una volta che ti sarai abituato a utilizzare questo schema, puoi impilarlo, con una cascata di LEFT JOIN operazioni, per ottenere molti attributi diversi, in questo modo.

     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

Ho fatto un sacco di indentazioni su questa query per rendere più facile vedere il modello. Potresti preferire uno stile di rientro diverso.

È difficile sapere perché stavi riscontrando problemi di prestazioni con la query nella tua domanda. Probabilmente è perché stavi ottenendo un'esplosione combinatoria con tutti gli INNER JOIN operazioni che sono state poi filtrate. Ma in ogni caso la query che hai mostrato probabilmente non stava restituendo righe.

Se riscontri ancora problemi di prestazioni, prova a creare un indice composto su postmeta sul (post_id, meta_key, meta_value) colonne. Se stai creando un plugin per WordPress, è probabilmente un lavoro da fare al momento dell'installazione del plugin.