首頁  >  問答  >  主體

提升WooCommerce會員查詢速度的建議:優化MySQL索引

<p>我有一個基於WooCommerce會員的網站,使用了Teams for WooCommerce會員擴充。儘管有龐大的用戶群體(> 70,000用戶),95%的時間它表現得非常好。我們每天接待約10,000個訪問,回應時間在一秒以下。 </p> <p>在用戶需要完成培訓的旺季期間,由於並發未快取請求的負載,網站可能會崩潰。 </p> <p>使用Query Monitor工具,有一個查詢引起了注意:0.0375秒(平均值小於0.0050秒)。這個查詢檢查以下內容:</p> <ol> <li><p>目前使用者是否是具有活躍訂閱的團隊的成員? </p> </li> <li><p>他們是否有權限查看這篇文章? </p> </li> </ol> <p>以下是查詢本身:</p> <pre class="brush:php;toolbar:false;">SELECT wp_posts.* FROM wp_posts LEFT JOIN wp_postmeta _teams_pm ON wp_posts.ID = _teams_pm.post_id AND _teams_pm.meta_key = '_member_id' AND _teams_pm.meta_value = 2 LEFT JOIN wp_usermeta _teams_um ON _teams_um.user_id = _teams_pm.meta_value AND _teams_um.meta_key = CONCAT( '_wc_memberships_for_teams_team_', wp_posts.ID, '_role' ) WHERE 1=1 AND ((wp_posts.post_type = 'wc_memberships_team' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled' OR wp_posts.post_status = 'private'))) AND ( _teams_um.meta_value IN('manager', 'member') OR wp_posts.post_author = 2 ) ORDER BY wp_posts.post_date DESC</pre> <p>它被以下呼叫:</p> <pre class="brush:php;toolbar:false;">"WP_Query->get_posts() wp-includes/class-wp-query.php:3111 WP_Query->query() wp-includes/class-wp-query.php:3542 WP_Query->__construct() wp-includes/class-wp-query.php:3653 SkyVergeWMTTeams_Handler->get_teams() wp-content/plugins/woocommerce-memberships-for-teams/src/Teams_Handler.php:446 wc_memberships_for_teams_get_teams() wp-content/plugins/woocommerce-memberships-for-teams/src/Functions/Teams.php:100 ctz_membership_get_user_team_id() wp-content/plugins/core-functionality/temp/wc_teams.php:603"</pre> <p>有人有任何關於如何加快此查詢速度的索引的想法嗎?我對SQL不夠熟悉,不知道最佳索引位置在哪裡。 </p> <p>我們預計週一會有一個大的峰值,所以我希望在本週末網站比較空閒的時候能有所準備。</p> <p>提前感謝! </p> <p>編輯:explain的輸出,前綴和資料庫名稱已匿名化:</p> <pre class="brush:php;toolbar:false;"> ---- ------------- --------------- - ----------- ------- ------------------------------ -- ---------------- --------- ------------------------- --------------------- ------ ---------- ------------- -------------------------- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | ---- ------------- --------------- ------------ ------ - ------------------------------ ------------------ - -------- ------------------------------------------ ---- ------ ---------- ------------------------------ --------- | 1 | SIMPLE | wp_posts | NULL | range | type_status_date,post_author | type_status_date | 164 | NULL | 5556 | 100.00 | Using index condition; Using filesort | | 1 | SIMPLE | _teams_pm | NULL | ref | PRIMARY,meta_key,meta_value | PRIMARY | 1030 | dbname.wp_posts.ID,const | 1 | 100.00 | Using where | | 1 | SIMPLE | _teams_um | NULL | ref | PRIMARY,meta_key | PRIMARY | 1030 | dbname._teams_pm.meta_value,func | 1 | 100.00 | Using where | ---- ------------- --------------- ------------ ------ - ------------------------------ ------------------ - -------- ------------------------------------------ ---- ------ ---------- ------------------------------ --------- 3 rows in set, 4 warnings (0.00 sec)</pre> <p><br /></p>
P粉333186285P粉333186285421 天前568

全部回覆(1)我來回復

  • P粉155710425

    P粉1557104252023-08-27 09:51:24

    那個外掛應該對一些查詢有幫助。

    這可能對wp_posts有幫助

    INDEX(post_type, post_status, post_author, ID, post_date)

    至於在一個表上有多個索引...不同的查詢需要不同的索引。 MySQL在每個表引用中只使用一個索引[很少例外]。在你的查詢中其實有3個查詢,一個是針對posts,另外兩個是針對postmeta。

    你提供的EXPLAIN似乎不一致。請提供兩個表的SHOW CREATE TABLE,這樣我可以弄清楚發生了什麼(並更好地回答Oliver的問題)。

    INDEX中的列的順序很重要;在WHERE子句中的順序則不重要。

    查詢中有兩個有問題的地方;避免它們可能有助於效能:CONCATOR。這是OR

    AND ( _teams_um.meta_value    IN('manager', 'member')
          OR wp_posts.post_author = 2 )

    沒有索引可以幫助。但是,由於應用程式的需求,可能無法改進它。

    回覆
    0
  • 取消回覆