sql >> データベース >  >> RDS >> Mysql

キー/値テーブルであるwp_postmetaへの多くの内部結合を使用してクエリを改善する

    タイプcarの投稿ごとに1行の結果セットを取得しようとしているようです。 。投稿に各車のさまざまな属性を表示したいようですが、それらはpostmetaに隠されています。 。

    プロのヒント:決して SELECT *を使用します なぜそれをしているのかを完全に理解していない限り、ソフトウェアで。特に、多くのJOINを含むクエリの場合 操作、SELECT * 無意味で冗長な列をたくさん返します。

    WordPressのpostmetaについて知っておくべきクエリデザインのトリックがあります テーブル。特定の属性を取得する場合は、次のようにします。

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

    あなたがやろうとしていることをするとき、このパターンを理解することは非常に重要です。 postmetaのため、このパターンが必要です は、 と呼ばれる特殊なタイプのテーブルです。 またはentity-attribute-value お店。何が起きてる?いくつかのこと:

    1. このパターンを使用すると、投稿ごとに1行を取得し、postsからいくつかの列を取得します。 テーブルとpostmetaの特定の属性 テーブル。
    2. あなたはLEFT JOIN postmetaを使用する テーブルなので、属性が欠落している場合でも行を取得できます。
    3. postmetaのエイリアス名を使用しています テーブル。これがpostmeta AS colorです 。
    4. meta_keyのセレクターを含めています (ここでは'color' = color.meta_keyON 参加の条件。
    5. SELECTでエイリアスを使用しています postmeta.meta_valueを提示する句 適切な列名を持つアイテム。これがcolor.meta_value AS colorです 。

    このパターンの採用に慣れたら、LEFT JOINのカスケードを使用してパターンを積み重ねることができます。 操作、そのように多くの異なる属性を取得します。

         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
    

    パターンを見やすくするために、このクエリにたくさんのインデントを加えました。別のインデントスタイルをお勧めします。

    質問のクエリでパフォーマンスの問題が発生した理由を理解するのは困難です。これは、すべてのINNER JOINとの組み合わせ爆発が発生したことが原因である可能性があります。 その後、フィルタリングされた操作。しかし、いずれにせよ、あなたが示したクエリはおそらく行を返さなかったでしょう。

    それでもパフォーマンスの問題が発生する場合は、postmetaに複合インデックスを作成してみてください (post_id, meta_key, meta_value) 列。 WordPressプラグインを作成している場合、それはおそらくプラグインのインストール時に行う作業です。



    1. PHP MySQL-6行ごとにdivを挿入しますか?

    2. グループ化/集約中に配列値を連結/マージします

    3. PostgreSQL12のデータベース管理と監視

    4. MySQLでテーブルの名前を変更する方法