最近一直在为降低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 来生成列表
评论