Tal*_*ili 5 mysql optimization
我正在使用一个名为feedwordpress的 WordPress 插件,以便在WordPress上运行一个类似网站的星球(它从其他网站获取内容,并获得他们的许可)(在此处查看)。
该插件很棒,除了一件事 - 它每周左右让我的(VPS)服务器提交一次。
在最近与网络管理员的电子邮件交流中,他写道:
看起来 mysql 资源使用量的增加确实是由 r-bloggers.com 运行的慢查询引起的。这是正在生成的一些日志的副本。您需要进一步优化此站点和数据库,以使其尽可能高效地运行。如果已经进行了这些更改,您最好的选择是考虑对您的 VPS 进行大规模升级,因为您的站点需要和看到的高级别或资源和流量。
以下是日志:
# Time: 110614 16:11:35
# User@Host: rblogger_rblogr[rblogger_rblogr] @ localhost []
# Query_time: 104 Lock_time: 0 Rows_sent: 0 Rows_examined: 54616
SELECT SQL_CALC_FOUND_ROWS wp_rb_posts.*
FROM wp_rb_posts
WHERE 1=1 AND (
(guid = '235cbefa4424d0cdb7b6213f15a95ded') OR
(guid = 'http://www.r-bloggers.com/?guid=235cbefa4424d0cdb7b6213f15a95ded') OR
(guid = 'http://www.r-bloggers.com/?guid=235cbefa4424d0cdb7b6213f15a95ded') OR
(MD5(guid) = '235cbefa4424d0cdb7b6213f15a95ded') ) AND
wp_rb_posts.post_type IN
('post', 'page', 'attachment', 'revision', 'nav_menu_item') AND
(wp_rb_posts.post_status = 'publish' OR
wp_rb_posts.post_status = 'future' OR
wp_rb_posts.post_status = 'draft' OR
wp_rb_posts.post_status = 'pending' OR
wp_rb_posts.post_status = 'trash' OR
wp_rb_posts.post_status = 'auto-draft' OR
wp_rb_posts.post_status = 'inherit' OR
wp_rb_posts.post_status = 'private'
)
ORDER BY wp_rb_posts.post_date DESC LIMIT 1570, 10;
# User@Host: rblogger_rblogr[rblogger_rblogr] @ localhost []
# Query_time: 237 Lock_time: 0 Rows_sent: 0 Rows_examined: 54616
SELECT SQL_CALC_FOUND_ROWS wp_rb_posts.* FROM wp_rb_posts WHERE 1=1 AND ((guid = '235cbefa4424d0cdb7b6213f15a95ded') OR (guid = 'http://www.r-bloggers.com/?guid=235cbefa4424d0cdb7b6213f15a95ded') OR (guid = 'http://www.r-bloggers.com/?guid=235cbefa4424d0cdb7b6213f15a95ded') OR (MD5(guid) = '235cbefa4424d0cdb7b6213f15a95ded')) AND wp_rb_posts.post_type IN ('post', 'page', 'attachment', 'revision', 'nav_menu_item') AND (wp_rb_posts.post_status = 'publish' OR wp_rb_posts.post_status = 'future' OR wp_rb_posts.post_status = 'draft' OR wp_rb_posts.post_status = 'pending' OR wp_rb_posts.post_status = 'trash' OR wp_rb_posts.post_status = 'auto-draft' OR wp_rb_posts.post_status = 'inherit' OR wp_rb_posts.post_status = 'private') ORDER BY wp_rb_posts.post_date DESC LIMIT 570, 10;
# Time: 110614 16:18:13
# User@Host: rblogger_rblogr[rblogger_rblogr] @ localhost []
# Query_time: 257 Lock_time: 0 Rows_sent: 0 Rows_examined: 54616
SELECT SQL_CALC_FOUND_ROWS wp_rb_posts.* FROM wp_rb_posts WHERE 1=1 AND ((guid = '956e208f101562f6654e88e9711276e4') OR (guid = 'http://www.r-bloggers.com/?guid=956e208f101562f6654e88e9711276e4') OR (guid = 'http://www.r-bloggers.com/?guid=956e208f101562f6654e88e9711276e4') OR (MD5(guid) = '956e208f101562f6654e88e9711276e4')) AND wp_rb_posts.post_type IN ('post', 'page', 'attachment', 'revision', 'nav_menu_item') AND (wp_rb_posts.post_status = 'publish' OR wp_rb_posts.post_status = 'future' OR wp_rb_posts.post_status = 'draft' OR wp_rb_posts.post_status = 'pending' OR wp_rb_posts.post_status = 'trash' OR wp_rb_posts.post_status = 'auto-draft' OR wp_rb_posts.post_status = 'inherit' OR wp_rb_posts.post_status = 'private') ORDER BY wp_rb_posts.post_date DESC LIMIT 570, 10;
# Time: 110614 16:19:02
# User@Host: rblogger_rblogr[rblogger_rblogr] @ localhost []
# Query_time: 83 Lock_time: 0 Rows_sent: 0 Rows_examined: 54616
SELECT SQL_CALC_FOUND_ROWS wp_rb_posts.* FROM wp_rb_posts WHERE 1=1 AND ((guid = '6c589e661f03a67b0529fab2f080bfd3') OR (guid = 'http://www.r-bloggers.com/?guid=6c589e661f03a67b0529fab2f080bfd3') OR (guid = 'http://www.r-bloggers.com/?guid=6c589e661f03a67b0529fab2f080bfd3') OR (MD5(guid) = '6c589e661f03a67b0529fab2f080bfd3')) AND wp_rb_posts.post_type IN ('post', 'page', 'attachment', 'revision', 'nav_menu_item') AND (wp_rb_posts.post_status = 'publish' OR wp_rb_posts.post_status = 'future' OR wp_rb_posts.post_status = 'draft' OR wp_rb_posts.post_status = 'pending' OR wp_rb_posts.post_status = 'trash' OR wp_rb_posts.post_status = 'auto-draft' OR wp_rb_posts.post_status = 'inherit' OR wp_rb_posts.post_status = 'private') ORDER BY wp_rb_posts.post_date DESC LIMIT 1440, 10;
Run Code Online (Sandbox Code Playgroud)
这引出了我的问题 - 此日志中的内容可能向我表明发生了什么(为什么此类查询需要这么长时间?)?是否可以优化这些?如果是这样,如何?
谢谢,塔尔
我看到的第一件事是 WHERE 子句中的 MD5(guid) = '235cbefa4424d0cdb7b6213f15a95ded'。这可能会触发绕过 MySQL 查询优化器并发出全表扫描以完成定位该行。
此外,尝试找出 guid 列是否在 wp_rb_posts 表中建立索引。
另外,当我看到“WordPress”时,我想到的是这个问题:你的所有数据都是 MyISAM 还是 InnoDB ???如果您的所有数据都是 MyISAM(在本例中为 wp_rb_posts 表),则始终期望在 MyISAM 表上的每个 INSERT、UPDATE 或 DELETE 时获得全表锁定。您可能需要考虑将所有 WordPress 数据转换为 InnoDB。这将减轻表锁定。
我转而将 MyISAM 转换为 InnoDB 的原因是什么?当有很多针对 wp_rb_posts 的 INSERT、UPDATES 或 DELETE(如果它当前是 MyISAM)时,每个都会在先到先得的基础上创建一个全表锁。任何 SELECT 查询,无论是执行好坏的查询,都只是等待轮到它,直到所有访问 wp_rb_posts 的查询看到 wp_rb_posts 表解锁并授予访问权限。
当这样的 SELECT 查询等待时,您可能会意识到运行时间正在攀升,这不是因为查询一定很糟糕,而是因为它在其生命周期中的大部分时间都在等待。因此,由于外部因素,例如运行相同查询的 DB 连接数、运行涉及 wp_rb_posts 的不同查询的 DB 连接数、整体服务器负载等,查询的运行时间可能具有欺骗性。同样值得注意的是 wp_rb_posts 中的行数。您需要了解此查询在独立测试环境中的运行时间是否不佳。
另一方面,如果 wp_rb_posts 已经是 InnoDB,现在您可以探索查询的 EXPLAIN 计划并查找被选择或忽略的索引。
以下是将所有 MyISAM 表转换为 InnoDB 的方法
作为一名 MySQL DBA,我相信 MySQL 会通过让 MySQL 为我编写脚本来完成转换。
形成 Linux 命令运行此查询
mysql -h... -u... -p... -A --skip-column-names -e"SELECT db,tb FROM (SELECT A.db,A.tb,A.tbsize FROM (SELECT table_schema db,table_name tb,(data_length+index_length) tbsize FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql')) A LEFT JOIN (SELECT table_schema db,table_name tb FROM information_schema.statistics WHERE index_type='FULLTEXT') B USING (db,tb) WHERE B.db IS NULL) AA ORDER BY tbsize" > /root/ConvertMyISAM2InnoDB.sql
Run Code Online (Sandbox Code Playgroud)
该脚本将首先转换最小的表。该脚本还绕过了任何具有 FULLTEXT 索引的 MyISAM 表。
查看脚本后,您可以简单地在 MySQL 中运行它,如下所示:
mysql -h... -u... -p... -A < /root/ConvertMyISAM2InnoDB.sql
Run Code Online (Sandbox Code Playgroud)
或者,如果您想查看每次转换的时间,请登录 mysql 并运行以下命令:
mysql> source /root/ConvertMyISAM2InnoDB.sql
Run Code Online (Sandbox Code Playgroud)
这不应该搞砸,因为在执行转换时会发生全表锁定。
转换所有表后,您需要针对 InnoDB 使用调整 MySQL 设置并缩小 key_buffer。
请阅读本文以设置 InnoDB 缓冲池:InnoDB 和 MyISAM 之间的主要区别是什么?
试一试 !!!
归档时间: |
|
查看次数: |
809 次 |
最近记录: |