Rest API DB killer query
-
In query-filters.php there is a hook to remove restricted content from the API but the query made is totally killing our database, it still runs after days:
// Use database-level filtering instead of post__not_in for better performance. // Handle both post-level meta restrictions and term-based restrictions. $args['meta_query'] = [ 'relation' => 'AND', [ 'relation' => 'OR', [ 'key' => '_is_paid', 'value' => '1', 'compare' => '!=', ], [ 'key' => '_is_paid', 'compare' => 'NOT EXISTS', ], ], [ 'relation' => 'OR', [ 'key' => 'rcp_subscription_level', 'compare' => 'NOT EXISTS', ], [ 'key' => 'rcp_subscription_level', 'value' => '', 'compare' => '=', ], ], [ 'relation' => 'OR', [ 'key' => 'rcp_user_level', 'compare' => 'NOT EXISTS', ], [ 'key' => 'rcp_user_level', 'value' => 'All', 'compare' => '=', ], ], [ 'relation' => 'OR', [ 'key' => 'rcp_access_level', 'compare' => 'NOT EXISTS', ], [ 'key' => 'rcp_access_level', 'value' => 'None', 'compare' => '=', ], ], ];This makes the following query:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts LEFT JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) LEFT JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id AND mt1.meta_key = ‘_is_paid’ ) LEFT JOIN wp_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id AND mt2.meta_key = ‘rcp_subscription_level’ ) LEFT JOIN wp_postmeta AS mt3 ON ( wp_posts.ID = mt3.post_id ) LEFT JOIN wp_postmeta AS mt4 ON ( wp_posts.ID = mt4.post_id AND mt4.meta_key = ‘rcp_user_level’ ) LEFT JOIN wp_postmeta AS mt5 ON ( wp_posts.ID = mt5.post_id ) LEFT JOIN wp_postmeta AS mt6 ON ( wp_posts.ID = mt6.post_id AND mt6.meta_key = ‘rcp_access_level’ ) LEFT JOIN wp_postmeta AS mt7 ON ( wp_posts.ID = mt7.post_id ) WHERE 1=1 AND ( ( ( wp_postmeta.meta_key = ‘_is_paid’ AND wp_postmeta.meta_value != ‘1’ ) OR mt1.post_id IS NULL ) AND ( mt2.post_id IS NULL OR ( mt3.meta_key = ‘rcp_subscription_level’ AND mt3.meta_value = ” ) ) AND ( mt4.post_id IS NULL OR ( mt5.meta_key = ‘rcp_user_level’ AND mt5.meta_value = ‘All’ ) ) AND ( mt6.post_id IS NULL OR ( mt7.meta_key = ‘rcp_access_level’ AND mt7.meta_value = ‘None’ ) ) ) AND wp_posts.post_type = ‘post’ AND ((wp_posts.post_status = ‘publish’)) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10
On our mariadb server it kills the database when accessing /wp-json/wp/v2/posts, tried on a newer mariadb version and it kills the query saying it exceeds max_join_size so it means the query is wrong. This with 20k posts and 400k post metas, this is a lot but the issue is with the query not our content..
You must be logged in to reply to this topic.