本文将继续来探讨Wordpress数据库查询的相关话题。文一里,我们知道了WP各个基准页面所需的数据库查询量。文二中,我介绍了利用WP自带技术实现降低数据库查询或读取次数的方法,将此法应用于模板中,可在不影响互动前提下,降低模板的数据库查询次数。如果您想了解下到底是那些函数或插件在消耗这些数据库查询呢?以及每个查询WP都从数据库中读什么东东呢?本文将帮您揭开这些问题的谜底。 

照旧,一切都是利用WP自带技术的。继续拿起铲子,深挖WORDPRESS。

首先,先用文本编辑器打开wp-config.php,加入如下代码: 

define(‘SAVEQUERIES’, true);

此行代码,将激活定义WP把每次数据查询的信息保存到数组内。然后用下述代码将数组内的各次数据库查询的信息显示出来,具体内容有三项:各次数据库查询的SQL代码,读取所消耗时间和执行数据库查询的函数名称。

   1: if (is_user_logged_in()){
   2:     global $wpdb;
   3:     echo "<pre>";
   4:     print_r($wpdb->queries);
   5:     echo "</pre>";
   6: }
 

来看看上面这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的服务器是最快也最直接有效的方法。嘿嘿,不过这也就少了分析的乐趣了。 

Feed Me


转载文章请注明转载自:ThinkAgain - Let's Blog!

引用地址:http://www.thinkagain.cn/archives/975.html