1. 在运行WP_Query 之前设置查询
尝试将数据库查询减至最少时,这似乎是要记住的最重要的事情,因为更改查询的唯一机会当然是在SQL数据库中运行之前。
普通查询
对于普通查询,WordPress使用此wp()
函数,该函数依次调用$wp->main( $query_vars )
。在将条件标签的“ is_变量”传递给之前,先对其进行设置WP_Query->get_posts()
,然后将其转换为MySQL数据库查询,最后将其存储在$ wp_query对象中。可以在SQL数据库中实际运行查询之前对其进行过滤。
该pre_get_posts
操作与该过程相关,可让您在将查询传递给之前对其进行更改WP_Query->get_posts()
。
例如,如果您要过滤查询“特色”类别中的帖子,则可以在中使用条件标记add_action( 'pre_get_posts', 'your_function_name' );
并将其包括in_category
在内your_function_name
。
function your_function_name( $query ) {
if ( $query->in_category( 'featured' ) && $query->is_main_query() ) {
// Replace 123 with the category ID of the featured category.
$query->set( 'cat', '123' );
}
}
add_action( 'pre_get_posts', 'your_function_name' );
请参阅插件API /操作参考/获取相关职位«WordPress Codex
页面请求
至于页面模板,例如“功能”类别的存档页面,条件标签将无法从pre_get_posts
过滤器中使用。例如,您不能使用is_category
来检查存档页面,因为WP_Query尚未运行。
相反,您必须使用来更改页面请求的主查询,new WP_Query
其外观类似于$query = new WP_Query( 'cat=123' );
。这将从一开始就使用适当的参数集运行查询。
请参阅类参考/ WP查询«WordPress Codex
2.保存到数据库
您可以使用过滤器,wp_insert_post_data
确保仅将与自定义帖子类型相关的$ data返回给wp_insert_post
。确保包含条件语句以检查您的自定义帖子类型。
插件API /过滤器参考/ WP插入帖子数据«WordPress Codex
该钩子由wp_insert_post
函数调用,该函数在您更新自定义帖子类型时通常由保存草稿或发布帖子来由wp_update_post调用。
不过,您必须自己对其进行基准测试,因为我个人无法谈到减少数据库中更新数据的优化意义。
3.自定义帖子类型会影响性能吗?
以我的经验,自定义帖子类型是用于管理内容的强大工具。我不知道有什么其他方式可以使用较少的资源来以允许的所有方式来管理帖子。我个人将重点放在寻找方法上,以尽可能减少查询的数量。
以前存在与永久链接结构相关的性能问题,导致其以文本开头而不是数字开头时会受到打击。3这对于承载大量页面的网站特别麻烦,但自WordPress 3.3版以来已解决。
我只在这里提到永久链接,因为该段通常是永久链接结构的第一部分,在3.3版本之前,它可能会或可能不会影响性能。除此之外,我不知道使用自定义帖子类型会引起任何性能问题。
其他性能选项
瞬态
这不是将代码中的查询保持在最少数量的替代方法,但是您可以使用set_transient将查询存储一段时间,这样就不需要新的查询了。这是Dave Clements帖子中使用的示例。另外,请注意,他建议save_post
在给定帖子类型更新后立即添加操作以删除瞬态。
<?php // IN THE SPOTLIGHT QUERY
if( false === ( $its_query = get_transient( 'its_query' ) ) ) {
$pttimestamp = time() + get_option('gmt_offset') * 60*60;
$its_query = new WP_Query( array(
'post_type' => 'spotlight',
'posts_per_page' => 1,
'post__not_in' => $do_not_duplicate,
'meta_query' => array(
array(
'key' => '_hpc_spotlight_end_time',
'value' => $pttimestamp,
'compare' => '>'
)
)
) );
set_transient( 'its_query', $its_query, 60*60*4 );
}
if( have_posts() ) { // HIDE SECTION IF NO CURRENT ITS FEATURE ?>
// LOOP GOES HERE: NOT IMPORTANT TO EXAMPLE
<?php } ?>
更多查询优化
Thomas Griffin在他的Optimize WordPress Queries教程中有一些不错的技巧。以下是他的建议的简要列表:
'cache_results' => false
如果您的服务器未使用持久性缓存(例如Memcached),请设置一次查询。一次性查询被描述为“用于显示少量数据的查询。可能是您只想显示与当前帖子相关的链接帖子标题,或者您可能想显示一个下拉列表来选择特定的选项设置。”
他的例子: $query = get_posts( array( 'posts_per_page' => 1,
'cache_results' => false ) );
设置'no_found_rows' => true
不需要分页的位置。这将“绕过MySQL计算结果以查看是否需要分页”。
他的例子: $query = new WP_Query( array( 'posts_per_page' => 1,
'no_found_rows' => true ) );
对于后期的ID只查询,如果这是你需要'fields' => 'ids'
在get_posts
。这将显着减少返回的数据量,如果您查看数据库描述,则每个帖子的数量很多
«WordPress Codex
他的例子: $query = get_posts( array( 'posts_per_page' => 1,
'fields' => 'ids' ) );
除了最后一个技巧外,当您只需要使用get_post_field一个或几个post字段时,可以应用相同的推理。
扎实的了解查询的工作原理至关重要。查询越具体,对SQL数据库的要求就越少。这意味着管理数据库查询有很多可能性。在自定义查询的运行位置(这是一个管理页面?)要小心,在直接查询中使用适当的清理方法,并尝试使用本机WordPress函数来实现相同的性能。