作为WordPress开发人员,我们经常需要从WordPress数据库中检索符合特定条件的文章、页面和其他内容。通常,我们不需要构建SQL查询(通常我们不应该),因为WP_Query
类及其方法为我们提供了一种从数据库中检索数据的安全有效的方法。我们只需要声明一个参数数组,$query
对象就会构建实际的SQL查询。
在这篇文章中,我将假设您已经了解WP_Query
类的基础知识、它的方法和属性,以及在哪里可以找到可用变量的列表。
我们将重点介绍WP_Query
类提供的参数,专门用于优化SQL查询,减少执行时间和资源消耗。
当流量和内容有限时,我们通常不会关心查询的效率。WordPress构建了优化良好的SQL查询,并提供了一个开箱即用的缓存系统。
当流量和网站内容显着增长时——多达数千个文章——那么我们必须考虑查询执行时间。
- 分页参数, 我们可以设置
posts_per_page
要从数据库中检索的行数。SQL_CALC_FOUND_ROWS
选项强制查询计算找到的行数。该数字将由SQL函数FOUND_ROWS()
返回,如以下示例所示:SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10; SELECT FOUND_ROWS();
不幸的是,
SQL_CALC_FOUND_ROWS
会显着减慢查询执行时间。好消息是我们可以强制WordPress删除提供未充分使用(且未记录)no_found_rows
变量的选项。如果省略了
SQL_CALC_FOUND_ROWS
,则FOUND_ROWS()
将返回最大值为LIMIT
的行数(MySQL文档中有关此主题的更多信息)。在包含数百个文章的WordPress安装中,以下元查询耗时0.0107秒:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON ( 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.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10
删除
SQL_CALC_FOUND_ROWS
,设置no_found_rows
为false,相同的查询需要0.0006秒。感谢Query Monitor插件,我们可以很容易地比较有和没有SQL_CALC_FOUND_ROWS选项的两个查询
当
wp_post
表包含数千行时,查询执行可能需要几秒钟。当我们不需要分页时,我们应该设置no_found_rows
为true
,使查询运行得更快。缓存或不缓存
WordPress提供了一个开箱即用的内置缓存系统。虽然缓存通常会提高页面加载速度,但它可能会导致对数据库运行一些额外的查询。此外,无论何时执行查询,都可能会请求一堆不必要的数据。
幸运的是,WordPress允许我们提供三个特定参数来禁用缓存:
- cache_results : 是否缓存文章信息。默认为true。
- update_post_meta_cache:是否更新文章meta缓存。默认为true。
- update_post_term_cache:是否更新文章term缓存。默认为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\'
字段。源文件文档定义fields参数如下:要返回的字段。单个字段或所有字段(字符串),或字段数组。’id=>parent’ 使用 ‘id’ 和 ‘post_parent’。默认所有字段。接受“ids”、“id=>parent”。
fields变量允许
\'ids\'
和\'id=>parent\'
,并且默认为 *(任何其他值),尽管您会注意到默认情况下WordPress会在多个查询中将该值设置为ids。最后,我们可以优化我们的第一个查询:<?php $args = array( \'no_found_rows\' => true, \'update_post_meta_cache\' => false, \'update_post_term_cache\' => false, \'category_name\' => \'cms\', \'fields\' => \'ids\' ); // The Query $the_query = new WP_Query( $args ); $my_posts = $the_query->get_posts(); if( ! empty( $my_posts ) ){ foreach ( $my_posts as $p ){ // Your code } } /* Restore original Post Data */ wp_reset_postdata(); ?>
当不需要特定字段时,将返回的字段限制为 ID。
小结
考虑到查询速度对于几百个帖子的小网站来说可能不会带来巨大的优势。如果您想为增长做好准备,或者您正在运行一个包含昂贵查询的大型网站,您应该优化您的 WordPress 查询。低效查询会显着减慢页面加载速度,但通过一些简单的调整,您可以大大加快您的网站速度。