1

我正在使用feedwordpress WordPress插件。

它使用在我的服务器上非常繁重的查询,我不确定如何(或是否)可以改进它们。Bellow 是我从托管公司获得的输出,是否有改进的希望?

(很抱歉没有更具体的问题,但我不知道如何 - 随时编辑问题以改进它 - 谢谢!)

most memory usage likely comes from the MySQL service:
Uptime: 3 hours 32 min 48 sec

Threads: 4 Questions: 761936 Slow queries: 254 Opens: 610 Flush tables: 1 Open tables: 603 Queries per second avg: 59.675

It is up 3 and a half hour and already had more than 250 slow queries, I will list the last few queries, and once you manage to optimize these I'm sure the memory usage will decrease as well:
# User@Host: rblogger_rblogr[rblogger_rblogr] @ localhost []
# Thread_id: 5737 Schema: rblogger_rblog Last_errno: 0 Killed: 0
# Query_time: 11.448474 Lock_time: 0.000059 Rows_sent: 0 Rows_examined: 66004 Rows_affected: 0 Rows_read: 66004
# Bytes_sent: 89 Tmp_tables: 0 Tmp_disk_tables: 0 Tmp_table_sizes: 0
# InnoDB_trx_id: 25335B6
SET timestamp=1366020031;
SELECT ID FROM wp_rb_posts WHERE to_ping <> '' AND post_status = 'publish';
# Time: 130415 5:01:01
# User@Host: rblogger_rblogr[rblogger_rblogr] @ localhost []
# Thread_id: 5785 Schema: rblogger_rblog Last_errno: 0 Killed: 0
# Query_time: 4.344107 Lock_time: 0.000129 Rows_sent: 2219 Rows_examined: 13192 Rows_affected: 0 Rows_read: 13192
# Bytes_sent: 23262206 Tmp_tables: 0 Tmp_disk_tables: 0 Tmp_table_sizes: 0
# InnoDB_trx_id: 25335D9
SET timestamp=1366020061;
SELECT wp_rb_posts.* FROM wp_rb_posts WHERE 1=1 AND (((wp_rb_posts.post_title LIKE '%git%') OR (wp_rb_posts.post_content LIKE '%git%'))) AND (wp_rb_posts.post_password = '') AND wp_rb_posts.post_type IN ('post', 'page', 'attachment') AND (wp_rb_posts.post_status = 'publish') ORDER BY wp_rb_posts.post_date DESC;
# Time: 130415 6:03:28
# User@Host: rblogger_rblogr[rblogger_rblogr] @ localhost []
# Thread_id: 8619 Schema: rblogger_rblog Last_errno: 0 Killed: 0
# Query_time: 7.299722 Lock_time: 0.000092 Rows_sent: 0 Rows_examined: 66005 Rows_affected: 0 Rows_read: 66005
# Bytes_sent: 89 Tmp_tables: 0 Tmp_disk_tables: 0 Tmp_table_sizes: 0
# InnoDB_trx_id: 2534534
SET timestamp=1366023808;
SELECT ID FROM wp_rb_posts WHERE to_ping <> '' AND post_status = 'publish';
# User@Host: rblogger_rblogr[rblogger_rblogr] @ localhost []
# Thread_id: 8620 Schema: rblogger_rblog Last_errno: 0 Killed: 0
# Query_time: 9.666021 Lock_time: 0.000037 Rows_sent: 0 Rows_examined: 66005 Rows_affected: 0 Rows_read: 66005
# Bytes_sent: 89 Tmp_tables: 0 Tmp_disk_tables: 0 Tmp_table_sizes: 0
# InnoDB_trx_id: 2534533
SET timestamp=1366023808;
SELECT ID FROM wp_rb_posts WHERE to_ping <> '' AND post_status = 'publish';
# Time: 130415 6:58:25
# User@Host: rblogger_rblogr[rblogger_rblogr] @ localhost []
# Thread_id: 11340 Schema: rblogger_rblog Last_errno: 0 Killed: 0
# Query_time: 4.616263 Lock_time: 0.000067 Rows_sent: 10 Rows_examined: 6014 Rows_affected: 0 Rows_read: 6014
# Bytes_sent: 189 Tmp_tables: 0 Tmp_disk_tables: 0 Tmp_table_sizes: 0
# InnoDB_trx_id: 253530A
SET timestamp=1366027105;
SELECT SQL_CALC_FOUND_ROWS wp_rb_posts.ID FROM wp_rb_posts WHERE 1=1 AND (wp_rb_posts.post_author = 56) AND wp_rb_posts.post_type = 'post' AND (wp_rb_posts.post_status = 'publish') ORDER BY wp_rb_posts.post_date DESC LIMIT 0, 10;

这是结果SHOW CREATE TABLE wp_rb_posts

CREATE TABLE `wp_rb_posts` (
 `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `post_author` bigint(20) unsigned NOT NULL DEFAULT '0',
 `post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `post_date_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `post_content` longtext NOT NULL,
 `post_title` text NOT NULL,
 `post_excerpt` text NOT NULL,
 `post_status` varchar(20) NOT NULL DEFAULT 'publish',
 `comment_status` varchar(20) NOT NULL DEFAULT 'open',
 `ping_status` varchar(20) NOT NULL DEFAULT 'open',
 `post_password` varchar(20) NOT NULL DEFAULT '',
 `post_name` varchar(200) NOT NULL DEFAULT '',
 `to_ping` text NOT NULL,
 `pinged` text NOT NULL,
 `post_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `post_modified_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `post_content_filtered` longtext NOT NULL,
 `post_parent` bigint(20) unsigned NOT NULL DEFAULT '0',
 `guid` varchar(255) NOT NULL DEFAULT '',
 `menu_order` int(11) NOT NULL DEFAULT '0',
 `post_type` varchar(20) NOT NULL DEFAULT 'post',
 `post_mime_type` varchar(100) NOT NULL DEFAULT '',
 `comment_count` bigint(20) NOT NULL DEFAULT '0',
 PRIMARY KEY (`ID`),
 KEY `post_name` (`post_name`),
 KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`),
 KEY `post_parent` (`post_parent`),
 KEY `wp_rb_posts_guid_idx` (`guid`),
 KEY `post_author` (`post_author`),
 KEY `guid` (`guid`)
) ENGINE=InnoDB AUTO_INCREMENT=69681 DEFAULT CHARSET=utf8

下一次诊断运行是:

EXPLAIN SELECT SQL_CALC_FOUND_ROWS wp_rb_posts.ID
FROM wp_rb_posts
WHERE 1 =1
AND (
wp_rb_posts.post_author =56
)
AND wp_rb_posts.post_type =  'post'
AND (
wp_rb_posts.post_status =  'publish'
)
ORDER BY wp_rb_posts.post_date DESC 
LIMIT 0 , 10

使用以下输出:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  wp_rb_posts ref type_status_date,post_author    post_author 8   const   5624    Using where; Using filesort
4

3 回答 3

3

首先,看看支持论坛上的这个帖子(我看到你也在那里寻求帮助)——你不是唯一一个有问题的人,这个帖子中有一些建议。

其次,使用远程托管的数据库来调试性能问题是一场可怕的游戏——尤其是如果这是您的实时服务器。为了您自己的理智,我强烈建议在您可以实际工作和试验的机器上重新创建系统。

您可能需要的最起码是让 MySQL 运行(最好与您的服务器版本相同),并从您的实时环境中恢复数据库。

接下来,进行运行缓慢的查询,并弄清楚发生了什么——据我所知,你最严重的违规者没有匹配的索引。

SELECT ID FROM wp_rb_posts WHERE to_ping <> '' AND post_status = 'publish';

将受益于 to_ping 和可能 post_status 的复合索引(该列的基数可能太低而无济于事)。

SELECT SQL_CALC_FOUND_ROWS wp_rb_posts.ID
FROM wp_rb_posts
WHERE 1 =1
AND (
wp_rb_posts.post_author =56
)
AND wp_rb_posts.post_type =  'post'
AND (
wp_rb_posts.post_status =  'publish'
)
ORDER BY wp_rb_posts.post_date DESC 
LIMIT 0 , 10

看起来它在大多数列中的基数也很低 - 但如果你有很多行,根据 post_date 选择前 10 名将会很昂贵;考虑 where 子句中所有列的复合索引,加上 post_date。

SELECT wp_rb_posts.* 
FROM wp_rb_posts 
WHERE 1=1 
AND (
     (
      (wp_rb_posts.post_title LIKE '%git%') 
     OR 
      (wp_rb_posts.post_content LIKE '%git%')
     )
    ) 
AND (wp_rb_posts.post_password = '') 
AND wp_rb_posts.post_type IN ('post', 'page', 'attachment') 
AND (wp_rb_posts.post_status = 'publish') 
ORDER BY wp_rb_posts.post_date DESC;

很讨厌——文本搜索应该真正使用自由文本搜索;对于大型数据集,这可能非常慢。如果您无法更改该查询,则不确定您可以做些什么来修复它 - 您可以在其他列上添加一个复合键,但在我看来,该查询会搜索所有当前帖子中的文本。

在您的本地机器上创建索引,测量它们是否有任何区别,并在理想情况下测试您没有破坏任何东西(例如通过意外添加唯一索引......)。

于 2013-04-15T22:42:35.147 回答
2
SELECT wp_rb_posts.* FROM wp_rb_posts WHERE 1=1 AND (((wp_rb_posts.post_title LIKE '%git%') OR (wp_rb_posts.post_content LIKE '%git%'))) AND (wp_rb_posts.post_password = '') AND wp_rb_posts.post_type IN ('post', 'page', 'attachment') AND (wp_rb_posts.post_status = 'publish') ORDER BY wp_rb_posts.post_date DESC;

至于一个,我确信一个问题是 % 通配符,在文字前后使用,即包含字符串操作。例如,更快的查询是 LIKE 'git%' - StartsWith 操作。至于其他查询,发布索引在表中的定义方式非常重要。

作为在某些情况下解决 %git% 问题的示例,我将创建一个触发器(我使用 MSSQL),它在插入/更新操作时将计算两者中是否包含“git”字符串记录的标题和内容,如果是,则将位字段标记为(真)。这会减慢表上的插入/更新操作(在一次只插入或更新一条记录时微不足道),但会大大提高搜索查询的性能。

于 2013-04-15T22:09:39.137 回答
1

有几个 Linux 软件包可以帮助您诊断和调整 MySQL 服务器,即:

  • 诺托普
  • mysql调谐器
  • 调音入门
于 2013-04-15T21:51:43.263 回答