使用WP_Query构建高效的WordPress查询

自学咖网努力为各位打造免费分享知识与教程网站

作为WordPress开发者,我们经常需要从WordPress数据库中检索符合特定条件的文章、页面和其他内容。通常,我们不需要构建SQL查询(通常我们不应该),因为WP_Query类及其方法为我们提供了一种安全有效的从数据库中检索数据的方法。我们只需要声明一个参数数组,而$query对象将构建实际的SQL查询。

在本文中,我将假设您已经了解WP_Query类的基础知识、它的方法和属性,以及在哪里可以找到可用变量的列表。

我们将重点介绍WP_Query类提供的参数,这些参数专门用于优化SQL查询,减少执行时间和资源消耗。

当流量和内容有限时,我们通常不关心查询的效率。WordPress构建了优化良好的SQL查询,并提供了开箱即用的缓存系统。

当流量和网站内容显著增加——多达数千篇——那么我们必须考虑查询执行时间。

我们的工具箱

WP _ Query–为什么我们不计算行数?

有或没有缓存。

返回的字段。

我们的工具箱

我将向您展示的代码已经通过了Query Monitor的测试,Query Monitor是一个免费的插件,它提供了关于查询性能、触发钩子、HTTP请求、重写规则等基本信息。

作为插件的替代方案,我们可以强制WordPress存储查询信息,并在wp-config.php中声明以下常量:

define( ‘SAVEQUERIES’, true );

当SAVEQUERIES设置为true时,WordPress将在$wpdb->queries数组中注册查询和一些有用的信息。因此,可以通过在footer.php这样的模板文件中添加以下代码来打印调用者函数的名称和每个查询的执行间隔:

if ( current_user_can( ‘administrator’ ) ) { global $wpdb; echo ”; print_r( $wpdb->queries ); echo ”;}

以下是回显内容的示例:

[4] => Array( [0] => SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = ‘post’ AND (wp_posts.post_status = ‘publish’ OR wp_posts.post_status = ‘private’) ORDER BY wp_posts.post_date DESC LIMIT 0, 10 [1] => 0.0163011550903 [2] => require(‘wp-blog-header.php’), wp, WP->main, WP->query_posts, WP_Query->query, WP_Query->get_posts, QM_DB->query [trace] => QM_Backtrace Object ( … ) [result] => 10)

如果你想深入研究这个话题,请查看我们的教程:编辑wp-config.php。最后,考虑到插件和内置的SAVEQUERIES是开发工具,我们应该在生产环境中关闭它们。

话虽如此,让我们来看看如何加快WordPress查询。

WP _ Query–为什么我们不计算行数?

我们可以使用get_posts函数查询数据库,该函数返回文章数组或WP_Query对象的新实例。在这两种情况下,我们都可以通过为特定变量设置适当的值来确定查询的结果。

让我们从一个例子开始,这个例子展示了通常出现在模板文件中的常见循环:

// The Query$the_query = new WP_Query( $args );// The Loopif ( $the_query->have_posts() ) { while ( $the_query->have_posts() ) : $the_query->the_post(); // Your code here endwhile;} else { // no posts found}/* Restore original Post Data */wp_reset_postdata();

$args是一个键/值对数组。这些对被命名为查询变量,并决定或影响实际的SQL查询。当从插件中查询数据库时,我们可能更喜欢使用pre_get_posts过滤器,如下例所示:

function myplugin_pre_get_posts( $query ) { if ( is_admin() || ! $query->is_main_query() ){ return; } $query->set( ‘category_name’, ‘webdev’ );}add_action( ‘pre_get_posts’, ‘myplugin_pre_get_posts’, 1 );

这里需要注意的重要一点是$query对象是通过引用传递的,而不是通过值传递的,这意味着查询参数只影响现有的$query实例。

set方法向查询规范添加了一个新的查询变量,并将强制WordPress从webdev类别中检索所有文章。这是查询结果:

SELECT SQL_CALC_FOUND_ROWS wp_posts.IDFROM wp_posts INNER JOIN wp_term_relationshipsON (wp_posts.ID = wp_term_relationships.object_id)WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (12) )AND wp_posts.post_type = ‘post’AND (wp_posts.post_status = ‘publish’OR wp_posts.post_status = ‘private’)GROUP BY wp_posts.IDORDER BY wp_posts.post_date DESCLIMIT 0, 10

在本例中,限制值是由管理员用户在读取选项中设置的,如下图所示。

自学咖网努力为各位打造免费分享知识与教程网站

在自定义查询中,我们可以根据分页参数设置posts_per_page从数据库中检索的行数。

SQL_CALC_FOUND_ROWS选项强制查询计算找到的行数。该数字将由SQL函数FOUND_ROWS()返回,如下例所示:

SELECT SQL_CALC_FOUND_ROWS * FROM tbl_nameWHERE id > 100 LIMIT 10;SELECT FOUND_ROWS();

不幸的是,SQL_CALC_FOUND_ROWS会显著降低查询的执行时间。好消息是,我们可以强制WordPress删除提供未充分利用(和未记录)的no_found_rows变量的选项。

如果省略SQL_CALC_FOUND_ROWS,FOUND_ROWS()将返回有限制的最大行数(有关此主题的更多信息,请参见MySQL文档)。

在包含数百篇文章的WordPress安装中,下面的元查询需要0.0107秒:

SELECT SQL_CALC_FOUND_ROWS wp_posts.IDFROM wp_posts INNER JOIN wp_postmetaON ( wp_posts.ID = wp_postmeta.post_id )WHERE 1=1 AND ( ( wp_postmeta.meta_key = ‘book_author’AND CAST(wp_postmeta.meta_value AS CHAR) LIKE ‘%Isaac Asimov%’ ) )AND wp_posts.post_type = ‘book’AND (wp_posts.post_status = ‘publish’OR wp_posts.post_status = ‘private’)GROUP BY wp_posts.IDORDER BY wp_posts.post_date DESCLIMIT 0, 10

删除SQL_CALC_FOUND_ROWS,设置no_found_rows为false,相同的查询需要0.0006秒。自学咖网努力为各位打造免费分享知识与教程网站请删除SQL _ CALC _发现_行并将no _发现_行设置为false。同样的查询需要0.0006秒。

多亏了查询监视器插件,我们可以很容易地比较使用和不使用SQL_CALC_FOUND_ROWS选项的两个查询。

当wp_post表包含数千行时,查询执行可能需要几秒钟。当我们不需要分页时,我们应该将no_found_rows设置为true,以使查询运行得更快。

有或没有缓存。

WordPress提供了一个开箱即用的内置缓存系统。尽管缓存通常可以提高页面加载速度,但它可能会导致对数据库运行一些额外的查询。此外,每当执行查询时,可能会请求大量不必要的数据。

幸运的是,WordPress允许我们提供三个特定的参数来禁用缓存:

Cache_results:是否缓存文章信息。默认值为true。

Update_post_meta_cache:是否更新文章元缓存。默认值为true。

Update_post_term_cache:是否更新文章词条缓存。默认值为true。

如果启用了持久缓存系统,比如Memcached,我们就不必关心缓存参数,因为WordPress会默认将这些参数设置为false。

在任何其他情况下,我们可以使用下面的代码来构建一个更快的查询:

function myplugin_pre_get_posts( $query ) { if ( is_admin() || ! $query->is_main_query() ){ return; } $query->set( ‘category_name’, ‘webdev’ ); $query->set( ‘no_found_rows’, true ); $query->set( ‘update_post_meta_cache’, false ); $query->set( ‘update_post_term_cache’, false );}add_action( ‘pre_get_posts’, ‘myplugin_pre_get_posts’, 1 );

当持久缓存系统不可用时,不应缓存返回少量数据的查询。

返回的字段。

一般来说,我们不应该查询数据库中不必要的字段。WP_Query类提供的字段参数,允许您限制返回字段的ID或’ id=>parent ‘字段。文件定义字段参数如下:

要返回的字段。单个字段或所有字段(字符串),或者字段数组。Id = > parent ‘使用’ Id ‘和’ post _ parent ‘。所有默认字段。接受“ids”和“id=>parent”。

fields变量允许使用’ ids ‘和’ id=>parent ‘,缺省值为*(任何其他值),尽管你会注意到WordPress缺省情况下在多个查询中将这个值设置为ids。最后,我们可以优化我们的第一个查询:

当不需要特定字段时,将返回的字段限制为ID。

总结

考虑到查询速度可能不会给几百个帖子的小网站带来很大优势。如果你想为增长做准备,或者你正在运行一个有昂贵查询的大型网站,你应该优化你的WordPress查询。低效的查询会显著降低页面加载速度,但通过一些简单的调整,你可以大大加快你的网站。

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » 使用WP_Query构建高效的WordPress查询