Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Melhorando uma consulta usando muitas associações internas para wp_postmeta, uma tabela de chave/valor


Parece que você está tentando obter um conjunto de resultados com uma linha por postagem do tipo car . Parece que você deseja exibir vários atributos de cada carro no post, e eles estão guardados em postmeta .

Dica profissional:Nunca use SELECT * em software, a menos que você saiba absolutamente por que está fazendo isso. Especialmente com consultas contendo muitos JOIN operações, SELECT * retorna muitas colunas inúteis e redundantes.

Há um truque de design de consulta para o WordPress postmeta tabela. Se você deseja obter um atributo específico, faça o seguinte:
 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 */

É muito importante entender esse padrão ao fazer o que você está tentando fazer. Este padrão é necessário porque postmeta é um tipo peculiar de tabela chamado ou armazenar. O que está acontecendo aqui? Algumas coisas:
  1. Usando este padrão você obtém uma linha para cada postagem, com algumas colunas das posts tabela e um atributo específico do postmeta tabela.
  2. Você está LEFT JOIN ndo o postmeta table para que você ainda receba uma linha se o atributo estiver ausente.
  3. Você está usando um nome alternativo para o postmeta tabela. Aqui está postmeta AS color .
  4. Você está incluindo o seletor para meta_key (aqui está 'color' = color.meta_key ) no ON condição da associação.
  5. Você está usando um alias em seu SELECT cláusula para apresentar o postmeta.meta_value item com um nome de coluna apropriado. Aqui está color.meta_value AS color .

Depois de se acostumar a empregar esse padrão, você pode empilhá-lo, com uma cascata de LEFT JOIN operações, para obter muitos atributos diferentes, assim.
     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

Eu fiz um monte de recuo nesta consulta para facilitar a visualização do padrão. Você pode preferir um estilo de recuo diferente.

É difícil saber por que você estava tendo problemas de desempenho com a consulta em sua pergunta. É possivelmente porque você estava recebendo uma explosão combinatória com todos os INNER JOIN operações que foram então filtradas. Mas, de qualquer forma, a consulta que você mostrou provavelmente não estava retornando nenhuma linha.

Se você ainda estiver tendo problemas de desempenho, tente criar um índice composto em postmeta no (post_id, meta_key, meta_value) colunas. Se você estiver criando um plug-in do WordPress, isso provavelmente é um trabalho a ser feito no momento da instalação do plug-in.