本文将继续来探讨Wordpress数据库查询的相关话题。文一里,我们知道了WP各个基准页面所需的数据库查询量。文二中,我介绍了利用WP自带技术实现降低数据库查询或读取次数的方法,将此法应用于模板中,可在不影响互动前提下,降低模板的数据库查询次数。如果您想了解下到底是那些函数或插件在消耗这些数据库查询呢?以及每个查询WP都从数据库中读什么东东呢?本文将帮您揭开这些问题的谜底。
照旧,一切都是利用WP自带技术的。继续拿起铲子,深挖WORDPRESS。
首先,先用文本编辑器打开wp-config.php,加入如下代码:
define(‘SAVEQUERIES’, true);
此行代码,将激活定义WP把每次数据查询的信息保存到数组内。然后用下述代码将数组内的各次数据库查询的信息显示出来,具体内容有三项:各次数据库查询的SQL代码,读取所消耗时间和执行数据库查询的函数名称。
来看看上面这6行代码,第1和6行代码用于判断当前用户是否是注册用户,如果您愿意让普通浏览者看见这些分析结果,可以将这2行代码去掉。第2行,定义全局变量$wpdb,这是WP默认的数据库类。第3和5行,定义将分析结果嵌套在HTML<pre>标签内。第4行将输出各次数据库查询的信息,print_r()是php的输出变量信息的函数。
将上述6行代码放置到默认模板或其它模板的footer.php的</body>标签前。打开页面,在页面的底部将会输出下列信息。注:如果有判断是否注册用户的代码,则必须是注册用户才能看到该信息。
如下例中,从0到8,共有9个数组,代表该页面总共发生了9次数据查询。每个数组里面包含3组信息,[0]为数据库查询所用的SQL代码,[1]查询所消耗的时间,基本上少都很少。Mysql效率还是非常高的。[2]为执行该次数据库查询的函数名称。
1: Array
2: (
3: [0] => Array
4: (
5: [0] => SELECT option_value FROM leo_options WHERE option_name = 'siteurl'
6: [1] => 0.00159311294556
7: [2] => is_blog_installed
8: )
9:
10: [1] => Array
11: (
12: [0] => SELECT option_name, option_value FROM leo_options WHERE autoload = 'yes'
13: [1] => 0.00426483154297
14: [2] => wp_load_alloptions
15: )
16:
17: [2] => Array
18: (
19: [0] => SELECT DISTINCT id FROM leo_wsdl_downloads WHERE status = '1' ORDER BY id ASC
20: [1] => 0.00153589248657
21: [2] => filetextInsert
22: )
23:
24: [3] => Array
25: (
26: [0] => SELECT ID, post_name, post_parent FROM leo_posts WHERE post_name = 'aboutme' AND (post_type = 'page' OR post_type = 'attachment')
27: [1] => 0.00170397758484
28: [2] => get_page_by_path
29: )
30:
31: [4] => Array
32: (
33: [0] => SELECT * FROM leo_posts WHERE ID = 2 LIMIT 1
34: [1] => 0.00132393836975
35: [2] => get_post
36: )
37:
38: [5] => Array
39: (
40: [0] => SELECT option_value FROM leo_options WHERE option_name = 'page_for_posts' LIMIT 1
41: [1] => 0.000607967376709
42: [2] => get_option
43: )
44:
45: [6] => Array
46: (
47: [0] => SELECT leo_posts.* FROM leo_posts WHERE 1=1 AND (leo_posts.ID = '2') AND leo_posts.post_type = 'page' ORDER BY leo_posts.post_date DESC
48: [1] => 0.000730991363525
49: [2] => get_posts
50: )
51:
52: [7] => Array
53: (
54: [0] => SELECT t.*, tt.*, tr.object_id FROM leo_terms AS t INNER JOIN leo_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN leo_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category', 'post_tag') AND tr.object_id IN (2) ORDER BY t.name ASC
55: [1] => 0.00423097610474
56: [2] => wp_get_object_terms
57: )
58:
59: [8] => Array
60: (
61: [0] => SELECT post_id, meta_key, meta_value FROM leo_postmeta WHERE post_id IN (2) ORDER BY post_id, meta_key
62: [1] => 0.0023729801178
63: [2] => update_postmeta_cache
64: )
65:
66: )
通过此信息,我们可以清楚地看到在打开该页面时,是那些WP内置函数或插件函数要求读取数据库。如上例中的,第3次数据查询是由filetextInsert函数造成的,这个是一个插件函数。分析下数据查询1和2,对应为Array[0]和Array[1],很显然,第1次查询是用于判断siteurl是否被赋值,siteurl值是存储在options表里面的。而第2次查询,是将options表里面所有autoload值为真的数据全部加载到内存中。文二中的Idea就是基于此数据查询的。注意下,在此有点不大理解,既然第2次查询是加载options表的数据,那么请问,如果将此数据查询放在第1,这样的话siteurl也已经被加载了,只需从内存中读取siteurl值就可以了,就没有必要再去读取options表内的siteurl的值了。简单地调换下次序,再修改下代码,这不就可以减少一次数据查询了。所以说,WP有时候是有点莫名其妙。p.s,is_blog_installed是在WP加载widget时候被调用的。
此文会数据库查询分析之三板斧的最后一篇。写这几篇文章的主要目的在于分享和探讨。通过这三篇文章,相信能对您了解Wordpress数据库查询的来龙去脉有所帮助。文二的方法主要用来减少模板的数据库查询,其idea也可以用在插件的制作上。通过本文,可以来判断那些插件的调用需要数据库查询,然后再结合其作用,综合判断是否需要该插件。通过此法,我将现有模板首页的查询次数,从36次降到16次。虽说每次数据库查询视SQL语句和数据量大小而定,消耗的时间并不多,如上例中,一般都在0.00几秒。但这个数值是在本地服务器上的测试结果,而放置到网站上的测试,您会发现加载同样的页面,消耗的时间不尽相同,有的时候,单个查询甚至会需要1秒以上,其原因是当时数据库的负载(同时请求数,连接数等)高造成的。撇开静态化完全不需要数据库查询不提,减低数据库查询以及精简php代码解析,是能有效提高WP的运行效率方法之一。当然,找个更Powerful的服务器是最快也最直接有效的方法。嘿嘿,不过这也就少了分析的乐趣了。
转载文章请注明转载自:ThinkAgain - Let's Blog!


























2008.07.29 Tuesday 9:59 pm
这个专业~~ 有帮助~
2008.07.29 Tuesday 10:25 pm
搞不懂啊 学习
2008.07.31 Thursday 9:53 pm
第1次查询是用于判断siteurl是否被赋值,siteurl值是存储在options表里面的。而第2次查询,是将options表里面所有autoload值为真的数据全部加载到内存中。
你这里也说到了 会把options里的数据存储到内存的siteurl里.
应该说第一个人打开了这个网页 那么这个网页的大部分数据都已经被存储到内存中,第二个人来访问的话 就直接读取内存的数据了.这就是缓存机制啦.
不过我只是猜想而已,因为我才学 php,和接触wp 两个月 .呵呵
实在不敢乱吹~~~
2008.08.01 Friday 9:45 am
@oyster: 应该要纠正下我的说法,wp是否自带缓存机制。其正确的说法应该是在早些版本,如2.3前,wp是有内置object cache缓存机制的,但是不知为何在新版中被取消了。现在来回答你的问题,wp是针对每个浏览者的动作,如打开页面等,作出相应的反馈的。所以,每次加载网页,那些查询等是会被执行的,并不是a打开页面加载了数据,b打开类似页面就不用加载数据了,如果是这样的话,那就是缓存了。而实际上并非如此的。
2008.08.07 Thursday 10:02 am
呵呵 可以继续发掘~~~
2008.11.08 Saturday 9:31 pm
对于优化Wordpress的博客很有用。
2010.11.20 Saturday 2:04 pm
[...] 为了减少数据库查询次数首先,先用文本编辑器打开wp-config.php,加入如下代码: define(‘SAVEQUERIES’, true); [...]