I have a fairly large database - 162150 total of rows in wp_3_posts table and 521345 total of rows in wp_3_postmeta. I noticed that my site is very slow. I noticed that the slow queries took like 10 seconds to load the page.
SELECT wp_3_posts.*
FROM wp_3_posts
INNER JOIN wp_3_postmeta
ON ( wp_3_posts.ID = wp_3_postmeta.post_id )
WHERE 1=1
AND ( ( wp_3_postmeta.meta_key = 'course_id'
AND wp_3_postmeta.meta_value = '157898' ) )
AND wp_3_posts.post_type IN ('sfwd-lessons', 'sfwd-topic', 'sfwd-quiz')
AND ((wp_3_posts.post_status = 'publish'
OR wp_3_posts.post_status = 'future'
OR wp_3_posts.post_status = 'draft'
OR wp_3_posts.post_status = 'pending'
OR wp_3_posts.post_status = 'private'))
GROUP BY wp_3_posts.ID
ORDER BY wp_3_posts.post_date DESC
I found out that meta_query arguments causes the page slow.
$attr_defaults = array(
'include_outer_wrapper' => 'true',
'num' => false,
'paged' => 1,
'post_type' => learndash_get_post_type_slug( 'course' ),
'post_status' => 'publish',
'order' => 'DESC',
'orderby' => 'ID',
'cat' => '',
'category_name' => 0,
'category__and' => '',
'category__in' => '',
'category__not_in' => '',
'categoryselector' => '',
'show_thumbnail' => 'true',
'show_content' => 'true',
'col' => '',
'progress_bar' => 'false',
'array' => false,
'course_grid' => 'true',
'update_post_term_cache' => false, // don't retrieve post terms
'update_post_meta_cache' => false, // don't retrieve post meta
'no_found_rows' => true, // counts posts, remove if pagination required
);
This is the table I am trying to optimize the meta_query arguments:
$enrollquery = $wpdb->get_results( $wpdb->prepare("SELECT Users.ID, Users.user_login, Users.display_name, Learndash.activity_type, PostObject.post_status, PostObject.post_title, PostObject.post_type FROM `wp_users` AS `Users`INNER JOIN `wp_3_learndash_user_activity` AS `Learndash` ON Users.ID = Learndash.user_id INNER JOIN `wp_3_posts` AS `PostObject` ON PostObject.ID = Learndash.post_id INNER JOIN `wp_3_postmeta` AS `Postmeta` ON PostObject.ID = Postmeta.post_id WHERE Users.ID = '".$current_user->ID."' GROUP BY PostObject.ID"));
Is there a way to optimize that?
First
Your question's second query is this, formatted.
I think it has a mistake in it. You do an INNER JOIN from
posts
topostmeta
, but you don't include ameta_key
filter. That means the query picks up all thepostmeta
rows for the post in question. That probably isn't right. It definitely makes the query handle a lot of extra data, only to have it removed by your GROUP BY.Usually
postmeta
joins look something like this:Pro tip always format your queries in your source code so you can read them easily. php allows multiline string constants.
Second
According to LearnDash's help page its table is defined
That table could use a change to an index, extending the
user_id
index to cover your query. You can do this with any MySQL client program. Make a backup first, and do it in a quiet time on your site. But, unless your users each do large numbers of activities, this index probably won't help much.Third
Your indexes on
posts
andpostmeta
need changing too. There's a plugin to handle those changes. Index WP MySQL For Speed. It creates indexes to cover queries like yours, described here.