这里是一个丑陋的极端慢由我们的Web应用程序生成的查询。这是一个自定义的Web应用程序,必须读取旧版Wordpress数据库。我需要写什么索引来防止在非高性能MySQL查询中进行表分类?
SELECT SQL_NO_CACHE DISTINCT
p.ID, p.post_title, p.post_name, p.post_excerpt, p.post_date, p.post_date_gmt, p.comment_count, post_content, post_author
FROM wp_posts p
INNER JOIN wp_term_relationships AS tr ON p.ID = tr.object_id
INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN wp_terms AS t ON tt.term_id = t.term_id
WHERE
tt.taxonomy = "post_tag"
AND p.post_type = "post"
AND p.post_password = ''
AND p.post_status = "publish"
ORDER BY p.post_date DESC
LIMIT 0, 20
为了给你这个数据库的大小的范围:
- wp_posts具有约250k行。
- wp_term_relationship有约。 1m行。
- wp_term_taxonomy有约。 50k行。
- wp_terms有大约50k行。
这里的EXPLAIN语句:
ID| SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS | KEY | KEY_LEN | REF | ROWS | EXTRA
1 | SIMPLE | tt | ref | PRIMARY,term_id_taxonomy,taxonomy | taxonomy | 130 | const | 27149 | Using index condition; Using temporary; Using filesort
1 | SIMPLE | t | eq_ref | PRIMARY | PRIMARY | 8 | wp_mu.tt.term_id | 1 | Using index
1 | SIMPLE | tr | ref | PRIMARY,term_taxonomy_id | term_taxonomy_id | 8 | wp_mu.tt.term_taxonomy_id | 11 | Using index
1 | SIMPLE | p | eq_ref | PRIMARY,type_status_date,optimize_slow_tax | PRIMARY | 8 | wp_mu.tr.object_id | 1 | Using where
据我所知道的,主要问题是,MySQL是生成一个临时表,并使用文件排序。
从我的阅读到目前为止,如果我能写出正确的查询,我们可以避免这整个崩溃。如果有必要创造一个母亲巨大的指数,我准备这样做。
我不是DBA,我不能轻松访问一个,所以我需要帮助来根据这个查询找出我应该写的东西。
- 我是否构建了此查询中涉及的所有
wp_posts
列的索引? - 或者只是所有
wp_posts
列涉及WHERE子句? - 或者只是所有
wp_posts
列涉及WHERE和ORDER BY子句?如果是这样,按什么顺序? - 或者只是所有
wp_posts
列涉及WHERE和ORDER BY和JOIN子句?如果是这样,按什么顺序? - 以任何方式重新排序WHERE子句的顺序,还是MySQL已经优化了这个?
- 如果我要创建一个MySQL视图,会有帮助吗?我的阅读暗示没有,但是最近的MySQL版本最近可能表现更好?
MySQL Views没有帮助,因为它们不是物化视图。每次查询视图时,您都会逐字运行相同的查询。所以视图更像宏。正如Rick回答的,失去了“DISTINCT”。 –
是的,我不这么认为。我想我可能希望MySQL 8.0有人认为让Views更高效,但也许MySQL用户刚刚接受了使用它们的训练。 – haz
我很想切换到Postgresql以获得物化视图,但可悲的是,这不是我做出的决定,这意味着它永远不会发生。 – haz