WordPress中WP_Query按date排序AJAX报500错,按title正常的原因疑问
问题:WordPress按日期排序文章触发内存耗尽,按标题排序却正常?
问题场景
我在WordPress中通过AJAX加载文章,需要实现按日期从旧到新/新到旧排序,但遇到了奇怪的问题:
- 按
title排序时,AJAX调用正常返回结果 - 按
date(无论ASC还是DESC)排序时,触发500错误
开启错误显示后,得到内存耗尽的报错:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /srv/www/wordpress/wp-includes/meta.php on line 1175
在.htaccess中添加php_value memory_limit 516M后问题解决,但我疑惑:为什么两种排序方式会有这么大的内存差异?
核心代码片段
排序查询部分:
// 按日期排序(报错) $sort =array( 'post_type' => 'post', 'post_status' => 'publish', 'order' =>'ASC', 'orderby' => 'date' ); // 按标题排序(正常) $sort =array( 'post_type' => 'post', 'post_status' => 'publish', 'orderby' => 'title', 'order' =>'ASC' );
完整AJAX处理函数:
function blogviewlist( $atts ){ global $post; $sort = array( 'post_type' => 'post', 'post_status' => 'publish', ); if(!empty($_REQUEST['keyword'])){ if ($_REQUEST['keyword']=="newtoold") { $sort =array( 'post_type' => 'post', 'post_status' => 'publish', 'orderby' => 'date', 'order' =>'DESC' ); } elseif ($_REQUEST['keyword']=="oldtonew") { $sort =array( 'post_type' => 'post', 'post_status' => 'publish', 'order' =>'ASC', 'orderby' => 'date' ); } } $getPost= new WP_Query( $sort ); if($getPost->have_posts()){ $data=''; $data.='<div class="blog-wrap"> <div class="row">'; while ( $getPost->have_posts()):$getPost->the_post(); $is_featureimage = wp_get_attachment_url( get_post_thumbnail_id($post->ID) ); $data.='<div class="col-lg-6 blog-post"> <div class="blog-list-item"> <a href="'.get_permalink($post->ID).'"><div class="item-img" style="background-image:linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)),url('.$is_featureimage.')"> </a> </div> </div>'; endwhile; $data.='</div></div>'; } echo $data; wp_die(); }
原因分析
两种排序方式的内存差异,本质是WordPress处理WP_Query时的查询执行逻辑和内存开销不同:
查询执行计划与索引利用差异
虽然post_date和post_title在WordPress的wp_posts表中都有索引,但按日期排序时,数据库的查询执行计划可能会触发更多关联数据的预加载(比如文章元数据、缩略图关联的附件数据),而按标题排序时,查询路径更直接,内存占用更低。临界内存限制的触发
你的PHP内存限制刚好是128M(134217728字节),按标题排序时,内存占用刚好低于这个阈值;而按日期排序时,查询过程中额外的内存开销(比如排序临时数组、钩子函数加载的额外数据)刚好超过了限制,触发了内存耗尽错误。无分页的潜在影响
你的查询中没有设置posts_per_page参数,默认会加载站点设置中“博客页面至多显示”的文章数量。如果这个数值较大,按日期排序时,一次性加载的文章及关联数据会带来更高的内存压力——相比标题排序,日期排序可能需要维护更大的临时数据集来完成排序逻辑。
优化建议
为了避免再次出现类似问题,可以对查询做以下优化:
- 显式设置
posts_per_page,限制单次加载的文章数量:$sort = array( 'post_type' => 'post', 'post_status' => 'publish', 'order' =>'ASC', 'orderby' => 'date', 'posts_per_page' => 10 // 根据需求调整数量 ); - 禁用不必要的缓存和计数,减少内存开销:
$sort = array( 'post_type' => 'post', 'post_status' => 'publish', 'order' =>'ASC', 'orderby' => 'date', 'posts_per_page' => 10, 'no_found_rows' => true, // 不需要分页计数时开启 'update_post_meta_cache' => false // 不需要访问文章元数据时开启 );
内容的提问来源于stack exchange,提问作者user9437856
相关产品推荐
相关产品推荐

