wordpress - 如何优化WP_Query(包括CPT和ACF)

我一直在 build 我的网站,今天正在使用 WP-plugin QueryMonitor 测试性能。一个特定页面上的页面加载时间为 30 秒!在那个页面上,我想打印出两种自定义帖子类型的列表——我有两个查询。一种自定义帖子类型有超过 3000 个帖子要处理,另一种可能有 400 个要处理。所有帖子都有 ACF 字段,我主要在页面上打印这些 ACF 字段。

QueryMonitor 给我: 页面生成时间 29,4764 30 秒限制的 98.3%

内存使用峰值 14 392 KB 131 072 kB 限制的 11.0%

数据库查询时间 29,3400

数据库查询 总计:37

缓存还没有打开,但是页面通常只访问一次等等,所以缓存可能不是答案。

我需要分页,所以 no_found_rows 不是答案。对于已经设置的其他查询,它稍微加快了页面速度。

我的问题查询如下所示:

$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$args = array(
    'posts_per_page' => 25,
    'post_type'      => 'horse',
    'paged'          => $paged,
    'meta_query'     => array(
        'relation' => 'AND',
        array(
            'key'     => 'owner_id_num',
            'value'   => $userid,
            'compare' => '=',
        ),
        array(
            'key'     => 'show_horse_profile',
            'value'   => '1',
            'compare' => '=',
        ),
    )
);
// query
$the_query = new WP_Query( $args );

我只是想知道如何才能加快查询速度。现在需要太多时间。

//编辑。尝试自定义查询,出现错误“[‘on 子句’中的未知列‘wp_posts.ID’]”。无法解决...

SELECT $wpdb->posts.* 
FROM $wpdb->posts, $wpdb->postmeta, $wpdb->postmeta AS mt1
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id 

AND $wpdb->postmeta.meta_key = 'owner_id_num'   
AND $wpdb->postmeta.meta_value = $userid
AND mt1.meta_key = 'show_horse_profile'
AND mt1.meta_value = '1'
AND $wpdb->posts.post_status = 'publish' 
AND $wpdb->posts.post_type = 'horse'

ORDER BY $wpdb->posts.post_date DESC

我正在尝试打印:

$total = $wpdb->get_var( "SELECT COUNT(1) FROM (${query}) AS combined_table" );
$items_per_page = $posts_per_page;
$page = isset( $_GET['cpage'] ) ? abs( (int) $_GET['cpage'] ) : 1;
$offset = ( $page * $items_per_page ) - $items_per_page;
$latestposts = $wpdb->get_results( $query . " LIMIT ${offset}, ${items_per_page}" );
?>
<table class="table horse-list-profile">
    <thead>
    <tr>
        <th>Hevonen</th>
        <th>Painotus</th>
        <th>Talli</th>
        <th>Ensiarvostelutulos</th>
    </tr>
    </thead>

<?php
foreach ($latestposts as $currentPost) {
    $breed_ID = get_field("breed");
    $breed = get_field("short", $breed_ID);
    $disc = get_field_object("discipline");
    $disc_value = $disc['value'];
    $disc_label = $disc['choices'][ $disc_value ];
    $skp = get_field_object('sex');
    $skp_value = $skp['value'];
    if ($skp_value == '0') { $sex = 't'; }
    else if ($skp_value == '1') { $sex = 'o'; }
    else if ($skp_value == '2') { $sex = 'r'; }
    ?>
    <tr>
        <td><?php echo $breed; ?>-<?php echo $sex; ?> <a href="<?php echo get_post_permalink(); ?>"><?php the_title(); ?></a></td>
        <td><?php echo $disc_label; ?></td>
        <td><?php if(get_field("stable_id", get_the_ID())) { echo get_the_title(get_field("stable_id", get_the_ID())); } else { echo '-'; } ?></td>
        <td><strong><?php echo get_field("basic_evaluation_grade"); ?></strong> <small><?php echo get_field("basic_evaluation_points"); ?>/1900p.</small></td>
    </tr>
<?php
}
?>
</table>

最佳答案

根据@SamiAhmedSiddiqui 的评论:

代码包括带有自定义分页菜单的自定义查询:

这就是我为我的网站制作它的方式,但也许您可以找到它的一些用途!

$posts_per_page = 10;
switch (filter_input(INPUT_GET, 'ppp')) {  
        case '10':
            $posts_per_page10 = "selected=true";
            $posts_per_page = 10;
            break;
        case '25':
            $posts_per_page25 = "selected=true";
            $posts_per_page = 25;
            break;
        case '50':
            $posts_per_page50 = "selected=true";
            $posts_per_page = 50;
            break;
}


global $wpdb;

$query = 

("SELECT $wpdb->posts.* 
    FROM $wpdb->posts, $wpdb->postmeta
        LEFT JOIN $wpdb->postmeta AS postmeta1
            ON (postmeta1.post_id = $wpdb->posts.id)
        LEFT JOIN $wpdb->postmeta AS postmeta2
            ON (postmeta2.post_id = $wpdb->posts.id)
    WHERE $wpdb->posts.post_type = 'horse'
    AND (postmeta1.meta_key = „owner_id_num“
        AND postmeta1.meta_value = $user_id
    )
    AND (postmeta2.meta_key = „show_horse_profile“
        AND postmeta2.meta_value = 1
    )")
;

$total = $wpdb->get_var( "SELECT COUNT(1) FROM (${query}) AS combined_table" );
$items_per_page = $posts_per_page;
$page = isset( $_GET['cpage'] ) ? abs( (int) $_GET['cpage'] ) : 1;
$offset = ( $page * $items_per_page ) - $items_per_page;
$latestposts = $wpdb->get_results( $query . " LIMIT ${offset}, ${items_per_page}" );

foreach ($latestposts as $currentPost) {
 //get post content
}

$pag = paginate_links( array(
    'base' => add_query_arg( 'cpage', '%#%' ),
    'format' => '',

    'show_all'           => false,
    'end_size'           => 0,
    'mid_size'           => 2,
    'prev_next'          => true,
    'prev_text'          => __('< Pref'),
    'next_text'          => __('Next >'),
    'type'               => 'array',
    'add_args'           => false,
    'add_fragment'       => '',
    'before_page_number' => '',
    'after_page_number'  => '',
    'total' => ceil($total / $items_per_page),
    'current' => $page
));



if(is_array($pag)){
    $last = end($pag);
    $first = reset($pag);
}


$prev = "";
$next = "";


if (\strpos($last, 'Next >') !== false) {
    $next = $last;
}
if(\strpos($first, '< Pref') !== false){
    $prev = $first;
}



<div class="paginationMenu">
    <div class="paginationPre">
        <?php echo $prev;?>
    </div>
    <div class="paginationPostsPerPage">
        Pagination:<select name="ppp" onchange="this.form.submit();">
            <option <?php echo $posts_per_page10?> value="10">10</option>
            <option <?php echo $posts_per_page25?> value="25">25</option>
            <option <?php echo $posts_per_page50?> value="50">50</option>
        </select>
    </div>
    <div class="paginationNext">
        <?php echo $next?>
    </div>
</div>

编辑:我根据这个 src 更改了查询:

https://wordpress.stackexchange.com/questions/40322/query-multiple-meta-key-values

$query = "  
        SELECT $wpdb->posts.* 
        FROM $wpdb->posts, $wpdb->postmeta, $wpdb->postmeta AS mt1
        WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id 

        AND $wpdb->postmeta.meta_key = 'key1'   
        AND $wpdb->postmeta.meta_value = 'value1'
        AND mt1.meta_key = 'key1'
        AND mt1.meta_value = 'value2'

        AND $wpdb->posts.post_status = 'publish' 
        AND $wpdb->posts.post_type = 'horse'
        ORDER BY $wpdb->posts.post_date DESC
        ";

https://stackoverflow.com/questions/57035284/

相关文章:

ios - 如果先前已加载某些网页,WKWebView 不会加载 .archive 文件

spring-boot - spring boot 微服务 docker 实现中 google oa

reactjs - 如何使用 Jest 和 Enzyme 在 nextjs 应用程序中编写单元测试

gcc - 从一个编译器版本到另一个编译器版本的符号重定位

json - 如何从 yang 模块生成 JSON 模式?

jenkins - BlueOcean编辑器 "scm"输入什么

flutter - 如何修复 flutter 上的 "A RenderFlex overflowed

c# - C# 中 C++ 结构化绑定(bind)的模拟

c# - 502 Bad Gateway nginx/1.14.1 elasticbeanstalk

reactjs - 在 nextjs 中,对象类型从服务器端更改为客户端