這裏是一個醜陋的極端慢由我們的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