0

我在 MU wordpress 网站上工作,我在查询中遇到问题,需要花费太多时间来执行。

SELECT wp_posts.* FROM wp_posts 
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) 
INNER JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id) 
INNER JOIN wp_terms ON (wp_term_taxonomy.term_id = wp_terms.term_id) 
WHERE 1=1 AND wp_posts.blog_id = '1'
AND wp_term_taxonomy.taxonomy = 'post_tag' 
AND wp_terms.slug IN ('rate') 
AND wp_posts.post_type = 'post' 
AND (wp_posts.post_status = 'publish') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC 
LIMIT 0, 20

这个由wordpress执行的查询,执行需要30-40秒,这太多了。

  • wp_posts : 4,00,000 行
  • wp_terms : 2,50,000 行
  • wp_term_relationship : 2,30,000 行
  • wp_term_taxonomy : 2,60,000 行

我已经索引了列(使用的)。

4

2 回答 2

0

For future, you can always re-edit your post and add content like the dump of an EXPLAIN (sql statement) as opposed to dumping into a comment.

The query itself looks pretty direct and your indexes per the explain appear ok, but for the WP_Posts table, I might change (or just add another index) based on

( Blog_ID, Post_Type, Post_Status, ID, Post_Date )

This way, it matches the criteria first, then the ID for optimizing the GROUP BY, and finally the Post_Date for Order By clause.

Next, so the engine doesn't try to work by some other reference table first, have you tried adding the keyword "STRAIGHT_JOIN" to it...

SELECT STRAIGHT_JOIN wp_posts.* ... rest of query

Another alternative I would consider is to pre-query just the IDs via distinct, then join back to the WP_Posts table... I don't know if its choking on you doing a SELECT * and grouping by just the ID.

SELECT
      wp_posts.* 
   FROM 
      ( SELECT STRAIGHT_JOIN DISTINCT 
              WP.ID
           from 
              wp_posts WP
                 INNER JOIN wp_term_relationships WPR
                    ON WP.ID = WPR.object_id
                    INNER JOIN wp_term_taxonomy WPTT
                       ON WPR.term_taxonomy_id = WPTT.term_taxonomy_id
                       INNER JOIN wp_terms WPT
                          ON WPTT.term_id = WPT.term_id
           WHERE 
                  1 = 1 
              AND WP.blog_id = '1'
              AND WP.post_type = 'post' 
              AND WP.post_status = 'publish'
              AND WPTT.taxonomy = 'post_tag' 
              AND WPT.slug IN ('rate') 
           GROUP BY 
              WP.ID 
           ORDER BY 
              WP.post_date DESC 
           LIMIT
              0, 20 ) JustIDs
      JOIN WP_Posts
         on JustIDs.ID = WP_Posts.ID
于 2013-06-14T13:33:47.677 回答
0

尝试并解释如下。

将以下内容粘贴到 phpmyadmin 并执行它:-

EXPLAIN SELECT wp_posts.* FROM wp_posts 
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) 
INNER JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id) 
INNER JOIN wp_terms ON (wp_term_taxonomy.term_id = wp_terms.term_id) 
WHERE 1=1 AND wp_posts.blog_id = '1'
AND wp_term_taxonomy.taxonomy = 'post_tag' 
AND wp_terms.slug IN ('rate') 
AND wp_posts.post_type = 'post' 
AND (wp_posts.post_status = 'publish') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC 
LIMIT 0, 20

然后复制结果并将它们粘贴到您的原始问题中。它将详细说明在哪些表中使用了哪些键等。

于 2013-06-14T12:00:58.557 回答