最近一直在為降低MySQL服務器負載努力,Drupal網站中主要是排查Views引起的性能問題,而MediaWiki中也有一個與Drupal的Views對應的工具:Dynamic Page List (DPL動态頁面列表),既可以靈活運用得到希望的信息展示效果,但同時也容易引起數據庫負載過高、性能下降。
當網站打開很慢的時候,還是需要查看阿裡雲RDS數據管理控制台DMS(Data Management Service),查看診斷報告或者當前實例會話,查看慢查詢語句,例如發現大量這樣的語句:
SELECT DISTINCT `jinglepage`.page_namespace AS page_namespace, `jinglepage`.page_title AS page_title, `jinglepage`.page_id AS page_id, rev_user, rev_user_text, rev_comment, rev_timestamp FROM `jinglerevision` AS rev, `jinglepage` INNER JOIN `jinglecategorylinks` AS cl0 ON `jinglepage`.page_id= cl0.cl_from AND(cl0.cl_to= '騙子号碼') WHERE 1= 1 AND `jinglepage`.page_namespace IN('0') AND `jinglepage`.page_is_redirect= 0 AND `jinglepage`.page_id= rev.rev_page AND rev.rev_timestamp=( SELECT MIN(rev_aux.rev_timestamp) FROM `jinglerevision` AS rev_aux WHERE rev_aux.rev_page= rev.rev_page) ORDER BY rev_timestamp DESC LIMIT 500 OFFSET 0
這是我們一個叫做“查号吧”網站中列出網友舉報的[[騙子号碼]]的頁面生成需要的MySQL查詢語句,這500個最新号碼是用DPL擴展程序列出的,Wiki中的源代碼如下:
{{#dpl: |namespace= |ordermethod = firstedit |order = descending |addeditdate = true |category = 騙子号碼 |adduser = true |mode = userformat |listseparators= ,¶# %DATE%: [[%PAGE%]] - %USER% }}
沒有想到其中列出首次編輯時間、增加用戶名稱等會讓SQL很要複雜一些起來,運行速度變慢,可以加入debug=3這個參數來顯示SQL語句以便調試。我後來采取了幾個措施:
- 去掉了adduser,不顯示%USER%信息了,這樣還可以避免用戶怕IP暴露;
- 排序條件從firstedit首次編輯時間改為pagetouched,也就是頁面更新時間(有可能是其使用的模闆變化引起);
- 顯示first edit date變為顯示page touched date;
- 增加了redirects重定向頁面也可以顯示列表。
具體源代碼改為:
{{#dpl: |ordermethod = pagetouched |order = descending |addpagetoucheddate = true |category = 騙子号碼 |redirects = include |mode = userformat |listseparators= ,¶# %DATE%: [[%PAGE%]] |debug = 3 }}
這樣可以看到SQL語句變為了:
SELECT DISTINCT `jinglepage`.page_namespace AS page_namespace, `jinglepage`.page_title AS page_title, `jinglepage`.page_id AS page_id, `jinglepage`.page_touched AS page_touched FROM `jinglepage` INNER JOIN `jinglecategorylinks` AS cl0 ON `jinglepage`.page_id= cl0.cl_from AND(cl0.cl_to= '騙子号碼') WHERE 1= 1 ORDER BY page_touched DESC LIMIT 500 OFFSET 0
明顯比前面的查詢條件簡單,實測運行時間從5004 ms下降到2902 ms。這樣顯示的列表沒有了首次編輯時間,從功能上說比原來稍微差一點,但不改動模闆的情況下,頁面更新時間和首次編輯時間是相同的,所以也還不太影響最後的顯示效果。
還有其它頁面(例如:[[首頁]])和模闆(例如:[[模闆:分類騙子]]、[[模闆:省份手機三位]]、[[模闆:省份手機四位]]、[[模闆:省份手機五位]]、[[模闆:運營商手機三位]]、[[模闆:運營商手機四位]]等)我也做了類似改動,綜合起來對改善服務器負載應該有好的作用。
MediaWiki的DPL列表功能沒有Drupal的Views靈活強大,也不是很方便控制最後的SQL語句,隻好多查看手冊,用一些條件來嘗試,對SQL語句運行進行對比,觀察RDS MySQL服務器的負載情況和診斷報告,從慢查詢是否減少來判斷效果。
補充參考資料:
- DPL:Manual - DPL parameters: Criteria for page selection
- Extension:DynamicPageList (third-party)
- 我們Wiki站中的DynamicPageList2
其中幾個可能用到的技巧:
- 調試SQL語句:增加|debug=3
- 去掉DISTINCT:distinct=false
- 增加了redirects重定向頁面也可以顯示列表:redirects=true
- 不要排序:ordermethod=none
- 返回數量:可改為較小或為1:
- 盡量用Title而不用其他字段構造内容顯示;
- 盡量少返回的數據,或者如果需要的話設定為1:count=10;
- 簡化分類,能不用的分類盡量不用,可結合namespace=example, matchtitle=example 來生成列表
评论