您在這裡

修改MediaWiki的動态頁面列表DPL設置降低MySQL負載

James Qi 在 2017年12月9日 - 19:33 發表

  最近一直在為降低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服務器的負載情況和診斷報告,從慢查詢是否減少來判斷效果。

  補充參考資料:

  其中幾個可能用到的技巧:

  • 調試SQL語句:增加|debug=3
  • 去掉DISTINCT:distinct=false
  • 增加了redirects重定向頁面也可以顯示列表:redirects=true
  • 不要排序:ordermethod=none
  • 返回數量:可改為較小或為1:
  • 盡量用Title而不用其他字段構造内容顯示;
  • 盡量少返回的數據,或者如果需要的話設定為1:count=10;
  • 簡化分類,能不用的分類盡量不用,可結合namespace=example, matchtitle=example 來生成列表

發表新回應

Plain text

  • 不允許使用 HTML 標籤。
  • 自動將網址與電子郵件地址轉變為連結。
  • 自動斷行和分段。