最近发现有一台阿里云RDS数据库服务器负载持续很高,CPU总是占满,当前连接数超过几十的时候网站就被卡得不能动了。除了升级RDS配置以外,可以仔细检查慢查询日志,发现这种查询特别多:
SELECT node.title AS node_title, node.nid AS nid, node.sticky AS node_sticky, node.created AS node_created FROM node node WHERE (( (node.status = 1 OR (node.uid = 0 AND 0 <> 0 AND 0 = 1) OR 0 = 1) AND (node.nid IN (SELECT tn.nid AS nid FROM taxonomy_index tn WHERE ( (tn.tid = '168') ))) )) ORDER BY node_sticky DESC, node_created DESC LIMIT 11 OFFSET 2600
这显然是一个Drupal网站的分类页面,翻页到后面产生的MySQL查询语句。执行的时间在2-4秒左右。
但其实分类页面的排序不重要,而且页面状态、当前用户也基本上是统一的、无需判断的,所以简化以上查询语句成这样:
SELECT node.title AS node_title, node.nid AS nid, node.language AS node_language FROM node node WHERE (( (node.nid IN (SELECT tn.nid AS nid FROM taxonomy_index tn WHERE ( (tn.tid = '168') ))) )) LIMIT 11 OFFSET 2600
执行的时间大约几十-几百ms,下降了1、2个数量级,所以这样的优化是很有效果的。
查到我以前就写过几篇类似博客《Drupal中启用Views来替代原生的分类页面》、《替换Views翻页功能来降低Drupal网站数据库负载》、《用Devel模块排查Drupal速度慢等性能问题》。
于是设置一个站的Views如下:
其中红框是改动了一些的地方,将这样设置的Views导出、复制到自定义模块的.views_default.inc文件中,并使用drush cc all批量清理系列站的缓存,就可以把这个Views应用到各个网站中。
评论