2016-04-11 16 views
1

私はWordpress 4.4.2を使用しています。Wordpress MySQLクエリの実行に時間がかかります

私の質問です:私は約314,000レコードのポストメタテーブルを持っています。次のクエリ(WordPressで構築)を実行しようとすると、実行には約5〜10秒かかります。

SELECT hf_posts.ID 
FROM hf_posts 
INNER JOIN hf_term_relationships 
ON (hf_posts.ID = hf_term_relationships.object_id) 

INNER JOIN hf_postmeta 
ON (hf_posts.ID = hf_postmeta.post_id) 

INNER JOIN hf_postmeta AS mt1 
ON (hf_posts.ID = mt1.post_id) 

INNER JOIN hf_postmeta AS mt2 
ON (hf_posts.ID = mt2.post_id) 


WHERE 1=1 
AND (hf_term_relationships.term_taxonomy_id IN (20)) 
AND (hf_postmeta.meta_key = 'match-date' 
AND ((mt1.meta_key = 'match-date' 
AND CAST(mt1.meta_value AS SIGNED) >= '1460091523') 
AND (mt2.meta_key = 'awaygame' 
AND CAST(mt2.meta_value AS CHAR) = '0'))) 
AND hf_posts.post_type = 'match' 
AND ((hf_posts.post_status = 'publish' 
OR hf_posts.post_status = 'future')) 
GROUP BY hf_posts.ID 
ORDER BY hf_postmeta.meta_value ASC 
LIMIT 0, 1 

私はすべてをチェックして、私は主な問題は、postmetaテーブルにあると結論:私は、単一のページでのクエリのこの種について持っているような2 - 単一のページを実行するために30秒 - 3回ので、20になります。このクエリの実行をスピードアップできるソリューションはありますか?

出力についての説明:

enter image description here

SHOWは、TABLE出力を作成:

CREATE TABLE `hf_postmeta` (
`meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
`post_id` bigint(20) unsigned NOT NULL DEFAULT '0', 
`meta_key` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
`meta_value` longtext COLLATE utf8_unicode_ci, 
PRIMARY KEY (`meta_id`), 
KEY `post_id` (`post_id`), 
KEY `meta_key` (`meta_key`(191)), 
KEY `meta_id` (`meta_id`), 
KEY `post_id_2` (`post_id`), 
KEY `meta_key_2` (`meta_key`), 
KEY `meta_key_3` (`meta_key`) 
) ENGINE=InnoDB AUTO_INCREMENT=326766 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 

をお返事を見て楽しみにしています。

よろしく、チラグ

+0

を必要とする...'と言いますこのクエリでは、質問に追加してください。 –

+0

悲しいかな、あなたはEAVスキーマが吸う理由の1つを見つけ出しています。関連するテーブルに 'SHOW CREATE TABLE'を指定した場合、部分的に修正される可能性があります。 –

+0

@AbhikChakraborty質問を編集しました –

答えて

0

SELECT p.ID 
    FROM hf_posts AS p 
    INNER JOIN hf_term_relationships AS r ON (p.ID = r.object_id) 
    INNER JOIN hf_postmeta AS mt0 ON (p.ID = mt0.post_id) 
    INNER JOIN hf_postmeta AS mt1 ON (p.ID = mt1.post_id) 
    INNER JOIN hf_postmeta AS mt2 ON (p.ID = mt2.post_id) 
    WHERE 1=1 
     AND r.term_taxonomy_id IN (20) 
     AND mt0.meta_key = 'match-date' 
     AND mt1.meta_key = 'match-date' 
     AND CAST(mt1.meta_value AS SIGNED) >= '1460091523' 
     AND mt2.meta_key = 'awaygame' 
     AND CAST(mt2.meta_value AS CHAR) = '0' 
     AND p.post_type = 'match' 
     AND (  p.post_status = 'publish' 
       OR p.post_status = 'future' 
      ) 
    GROUP BY p.ID 
    ORDER BY mt0.meta_value ASC 
    LIMIT 0, 1 

可能な場合は、hf_postmetaの最初のインスタンスを取り除く(私は...それはそれを理解するためにprettyprintしなければなりませんでした)。注文のためにmeta_valueを提供するだけですが、mt1で同じ値をフェッチしています。

可能であれば、hf_postsを取り除いてください。それは何も提供していないようです。 p.IDの代わりにr.object_idを使用できます。これは同じものとして知られています。

5の代わりに3つのテーブルを使用すると、パフォーマンスが向上します。

ありhf_postmetaで3つの冗長インデックスがありますが、あなたも、あなたが必要と2を持っていない:

INDEX(post_id, meta_key) 
INDEX(meta_key, post_id) 

そしてhf_term_relationshipsは `選択説明しない何

INDEX(term_taxonomy_id, object_id) 
INDEX(object_id, term_taxonomy_id) 
関連する問題