优化 WordPress 中的重慢查询

发布于 2025-01-20 05:28:50 字数 2455 浏览 2 评论 0原文

我有一个相当大的数据库-162150 WP_3_POSTS表中的行总计和521345 WP_3_POSTMETA中的行总数。我注意到我的网站非常慢。我注意到缓慢的查询花了大约10秒钟的时间来加载页面。


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 

我发现meta_query参数导致页面慢。

$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 
   );

这是我试图优化meta_query参数的表:

$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"));

有没有办法优化它?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暗恋未遂 2025-01-27 05:28:50

首先,

您的问题的第二个查询是格式化。

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

我认为这有一个错误。您可以从portspostmeta进行内部加入,但您不包括meta_key filter。这意味着查询会为所讨论的帖子拾取所有postmeta行。那可能不正确。它肯定会使查询处理很多额外的数据,只是通过您的小组将其删除。

通常,postmeta加入看起来像这样的东西:

 INNER JOIN wp_3_postmeta AS Postmeta
        ON PostObject.ID = Postmeta.post_id
       AND Postmeta.meta_key = 'course_id'  /* or some other constant */ 

Pro Tip 始终在源代码中格式化查询,因此您可以轻松阅读它们。 PHP允许多行字符串常数。

第二个

根据 nofollow noreferrer“> learnddash的帮助

CREATE TABLE wp_learndash_user_activity (
  activity_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  user_id bigint(20) unsigned NOT NULL DEFAULT '0',
  post_id bigint(20) unsigned NOT NULL DEFAULT '0',
  activity_type varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  activity_status tinyint(1) unsigned DEFAULT '0',
  activity_started int(11) unsigned DEFAULT NULL,
  activity_completed int(11) unsigned DEFAULT NULL,
  activity_updated int(11) unsigned DEFAULT NULL,
  PRIMARY KEY (activity_id),
  KEY user_id (user_id),
  KEY post_id (post_id),
  KEY activity_status (activity_status),
  KEY activity_type (activity_type),
  KEY activity_started (activity_started),
  KEY activity_completed (activity_completed),
  KEY activity_updated (activity_updated)
)

页面使用更改索引,将user_id索引扩展到 cover 您的查询。您可以使用任何MySQL客户端程序执行此操作。 首先进行备份,然后在您的网站上安静的时间进行备份。但是,除非您的用户每个人进行大量活动,否则此索引可能不会有太大帮助。

ALTER TABLE wp_3_learndash_user_activity
    DROP INDEX user_id,
    ADD INDEX user_id (user_id, post_id, activity_type);

第三,

您的索引帖子postmeta也需要更改。有一个插件来处理这些更改。 index wp mysql for speed 。它创建索引以涵盖像您这样的查询,

First

Your question's second query is this, formatted.

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

I think it has a mistake in it. You do an INNER JOIN from posts to postmeta, but you don't include a meta_key filter. That means the query picks up all the postmeta 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:

 INNER JOIN wp_3_postmeta AS Postmeta
        ON PostObject.ID = Postmeta.post_id
       AND Postmeta.meta_key = 'course_id'  /* or some other constant */ 

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

CREATE TABLE wp_learndash_user_activity (
  activity_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  user_id bigint(20) unsigned NOT NULL DEFAULT '0',
  post_id bigint(20) unsigned NOT NULL DEFAULT '0',
  activity_type varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  activity_status tinyint(1) unsigned DEFAULT '0',
  activity_started int(11) unsigned DEFAULT NULL,
  activity_completed int(11) unsigned DEFAULT NULL,
  activity_updated int(11) unsigned DEFAULT NULL,
  PRIMARY KEY (activity_id),
  KEY user_id (user_id),
  KEY post_id (post_id),
  KEY activity_status (activity_status),
  KEY activity_type (activity_type),
  KEY activity_started (activity_started),
  KEY activity_completed (activity_completed),
  KEY activity_updated (activity_updated)
)

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.

ALTER TABLE wp_3_learndash_user_activity
    DROP INDEX user_id,
    ADD INDEX user_id (user_id, post_id, activity_type);

Third

Your indexes on posts and postmeta 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文