今年4、5月份在用Drupal搭建英文版中国邮编网站China Postal Code的过程中,为了让浏览者更方便、更习惯,采用了CCK字段+Views展示的扩展模块,并进行一系列的比较复杂的设置,例如多个computed计算字段、Views查询中嵌套多级查询,算是基本上能实现所希望的功能。
但当时就发现在性能上有很多的问题,通过Devel模块的开启,可以查看到一些Views查询数据库所用的时间非常长,需要几十甚至几百秒,常常令服务器负载过高而影响网站访问。后来找了一个自动检测MySQL进程的小脚本,当发现超过限定值的进程时就自动kill掉,这个办法确实可行,但属于治标不治本,没有查到真实原因的情况下,不得已而为之,因为这样还会影响用户浏览和搜索引擎机器人的爬取。
上个月在下半年搭建的新网站中添加了多种Views来方便提供给用户更多功能,但很快就发现与上面这个站说的情况一样,服务器负载明显升高,MySQL的消耗很大,一些查询需要的时间太长,同时有很多查询的时候,服务器就无法处理得过来了。当时没有办法,只有临时去掉了这些Views提供的功能,还用Squid对这些网址进行了拒绝,并在robots.txt中设置了不要收录这些网址。
上周英文中国邮编站所在服务器的负载情况更突出一些,和多位同事反复商量讨论,也咨询外面高手,对这些Views的MySQL查询语句进行了详细分析。先是发现这些语句中有大量LEFT JOIN,因为多个字段不是存放在同一张表中,而是分布在多个表中,靠vid, nid来关联,我认为这是最大的问题,于是花了两天的时间来试验修改MySQL中数据库的结构,将一些字段合并到同一个表中(需要进行的工作步骤和代码用另外一篇博文记录)。
但花了很多时间做了以上工作后,发现以前查询时间过长的Views依然表现和以前差不多,没有得到明显改善。只有另外再想办法了,前面在咨询、商量中,别人也提出过字段的索引问题,昨天就在Views涉及到的字段上添加了Index,结果很快就发现效果非常明显,查询时间从几十、几百秒缩短到几秒、十几秒。经过一天的观察,再也没有出现服务器负载过高的情况了,等明天在周一访问高峰期再观察看看。如果证实了这种办法有效,而且没有其他负面作用,还可以推广到其他需要的网站上去。
评论