加速blog:监测和优化WordPress数据库 今天是及其黑暗的一天
Jun 02

一直以来,一直都想重新写个简洁高效版的WORDPRESS,这2天动手写了一下,发现了一些WORDPRESS速度慢的一些主要原因。以及我的解决方法。

1. 一篇文章多个分类:
每篇文章可以同时属于多个分类,在 wp_post2cat 中来实现一篇文章属于多个分类,这样就会造成列表查询时,为了得到每一篇文章的所属分类,会有非常多次数的查询

下面我说说WP中每一篇文章的分类链接是如何出来的:
1.1 显示列表时,会先从wp_posts中取出ID,标题,内容等主要字段
1.2. 再根据上一步得到的文章ID 在wp_post2cat中选择分类ID
1.3. 再根据得到分类ID后,再到`wp_categories`这个表中取每个分类ID的名称等内容

每一个条列表里的文章都要重复进行这些操作,数据库查询次数太多了!不断的频繁向`wp_post2cat`和`wp_categories`表查询,这是瓶颈所在。

如果一篇文章只属于一个分类,就会非常快,因为只需要一次查询就搞定了,ID,标题,分类,内容,都可以一次性取得.而WP设计的结构就是这样,没有办法避免.所以只能从其他方面考虑优化。

解决方案:
在不改变WORDPRESS数据库结构的情况下,可以将整个`wp_categories`输出文本数组进行缓存,这样要取得分类名称,就可以直接从数组中取,速度快好几倍。
备注:本来我想将分类字段改成内容像 1,2,3 这样的字段,这样就可以实现一篇文章多个分类,但是反过来,要查询某一分类的文章,就不行了,还需要另外的表,所以wordpress的数据库表结构并没 有什么问题,关键还是在于程序!另外在研究WORDPRESS数据库表的时候,发现有好多字段都设置得很大,像可以用TEXT的它却用LONGTEXT, 可以用INT(10)的它却用INT(20)等等

分类的缓存,可以在后面我说到的根据首页缓存来定时更新,除非你闲着没事整天改文章的分类。

2. 边栏按月归档 ARCHIVE的分月列表
这是取月份列表的SQL语句

SELECT DISTINCT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM `wp_posts` WHERE post_type = post AND post_status = publish GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC

这部份执行时间是比较多的,为了取得月份列表,对整个wp_posts表进行查询,实在不应该!而且每个页面,都会有这个操作!
这部份最最应该缓存!!!因为这玩意一个月更新一次缓存都可以了,不缓存的话,当文章有几万的时候,每个页面进行这个操作,是相当可怕的!
这部份缓存后只是一个数组,执行时间几乎是0
说到这里,还有个日历的区域,这个比按月归档要猛得多了,我觉得可以删除了,没有什么实际意义。

3. 边栏的分类列表
这部份看似简单,也要进行很多次数据库查询!虽然执行时间不算多,但查询次数实在太多了,因为有上下级的关系,这部份不必细说,和其他 CMS的分类表基本差不多,进行分类缓存后,这部份的速度,提升10倍,同时,也应用于上面的第一点。

WORDPRESS的程序结构设计的过于强大和复杂,数据库查询他本身已经是优化了的,要相信世界上这么多程序高手在写这个程序
正是因为这个强大的原因,程序考虑到太多的变动原因和太多的情况判断,导致效率非常低下,结构非常复杂,把一些非常简单的事都复杂化了

4. TAG部份
如果使用到TAG,和分类表基本一样的,最好也进行缓存
说到底,要速度快,就要进行缓存,进行最少次数的数据库查询,程序简单,再加上缓存,效率自然就高

目前WORDPRESS有WP-CACHE这个PLUGIN可以来做缓存用,但缺点太多
1. WP-CACHE是对整页进行缓存
2. 整站所有页面缓存时间都相同,无法控制首页,列表页,TAG页,搜索结果页,文章页不同的缓存时间

我重写的WORDPRESS只写完列表页和文章页,有2个版本
一个是超级优化的,仍然用WORDPRESS的原版数据库,分类和ARCHIVE缓存,不进行分类表的查询
将这些查询很耗时间的东西都做成局部缓存,在这一层之上,再做整页缓存,可以控制首页,列表页,TAG页,搜索结果页,文章页不同的缓存时间
内容仍然和WORDPRESS基本一样,包括标题,时间,分类,内容等
在3万文章的情况下,每页执行时间没有超过0.01秒的,而默认的WORDPRESS最少也要0.7秒,相差70倍,放到空间上,一页执行个6秒都是正常的,更不用说高负载的情况了,不被停空间才怪!
用上了局部缓存+整页缓存,优化到最后,执行时间基本和静态页面一致,因为最终的就是读取整个缓存页面

另一个是不进行缓存的版本,执行时间最少也在0.3秒以上,才发现,不缓存,对多个表进行查询进行多次查询是难免的,提升不了太大的效率

期待WORDPRESS也能应用好缓存,为爱好者们省点CPU资源吧。MYSQL不是那么好查询的,别没事整天查

written by allen

Leave a Reply

You must be logged in to post a comment.