大型数据库导致加载速度较慢

时间:2013-03-11 作者:Ruriko

我有一个2GB的WordPress数据库(使用InnoDB存储引擎),当我在媒体库中选择了一幅特色图片后,按下“发布”按钮时,我注意到我的网站加载速度很慢。

我看了一下我的桌子,注意到wp_postmeta 是最大的桌子wp_posts 在所有表格中排名第二。

有没有办法加快我的负荷?数据库为InnoDB

1 个回复
最合适的回答,由SO网友:RolandoMySQLDBA 整理而成

免责声明:不是WordPress开发人员,只是MySQL DBA,Oracle中有一种特殊的表结构,称为物化视图。基本上,它是通过执行连接查询(使用no-WHERE子句)和存储结果集来构建的。然后,只需从静态结果集中进行选择,而不是重建每个连接结果。

首先,让我们看看这两个表:

wp\\U邮差

mysql> show create table wp_postmeta\\G
*************************** 1. row ***************************
       Table: wp_postmeta
Create Table: CREATE TABLE `wp_postmeta` (
  `meta_id` bigint(20) unsigned NOT NULL auto_increment,
  `post_id` bigint(20) unsigned NOT NULL default \'0\',
  `meta_key` varchar(255) default NULL,
  `meta_value` longtext,
  PRIMARY KEY  (`meta_id`),
  KEY `post_id` (`post_id`),
  KEY `meta_key` (`meta_key`)
) ENGINE=MyISAM AUTO_INCREMENT=2926 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

wp\\U岗位

mysql> show create table wp_posts\\G
*************************** 1. row ***************************
       Table: wp_posts
Create Table: CREATE TABLE `wp_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` text 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 `post_author` (`post_author`)
) ENGINE=MyISAM AUTO_INCREMENT=59921 DEFAULT CHARSET=utf8
在数据库世界中,这听起来可能相当丑陋,但需要的是一个笛卡尔积,它将显示为一个正则表。

振作起来,这将是相当令人不安的。。。

DROP TABLE IF EXISTS wp_posts_postmeta_joined;
CREATE TABLE wp_posts_postmeta_joined SELECT * FROM wp_posts WHERE 1 = 2;
ALTER TABLE wp_posts_postmeta_joined
    ADD COLUMN `meta_key` varchar(255) default NULL,
    ADD COLUMN `meta_value` longtext
;
ALTER TABLE wp_posts_postmeta_joined ENGINE=MyISAM;
ALTER TABLE wp_posts_postmeta_joined ROW_FORMAT=Fixed;
ALTER TABLE wp_posts_postmeta_joined
      ADD INDEX status_ndx (`ID`,`status`),
      ADD INDEX `post_name` (`ID`,`post_name`),
      ADD INDEX `type_status_date` (`ID`,`post_type`,`post_status`,`post_date`),
      ADD INDEX `post_parent` (`ID`,`post_parent`),
      ADD INDEX `post_author` (`ID`,`post_author`),
      ADD INDEX `id_meta_key`(`ID`,`meta_key`)
;
ALTER TABLE wp_posts_postmeta_joined DISABLE KEYS;
INSERT INTO wp_posts_postmeta_joined 
    SELECT A.*,B.meta_key,B.meta_value
    FROM wp_posts A LEFT JOIN wp_postmeta B
    ON A.ID = B.post_id
;
ALTER TABLE wp_posts_postmeta_joined ENABLE KEYS;
基本上,所有的东西和厨房的水槽都在这张桌子上。您可以使用此表运行SELECT查询。有任何查询执行得不好吗?只需将所需的索引添加到脚本中并重建它。

警告#1

只要表格可以在下班时间重建并在工作日开始前可用,此过程就值得一试。您可以在重建过程中通过以下方式运行旧副本:

DROP TABLE IF EXISTS wp_posts_postmeta_joined_new;
CREATE TABLE wp_posts_postmeta_joined_new SELECT * FROM wp_posts WHERE 1 = 2;
ALTER TABLE wp_posts_postmeta_joined_new 
    ADD COLUMN `meta_key` varchar(255) default NULL,
    ADD COLUMN `meta_value` longtext
;
ALTER TABLE wp_posts_postmeta_joined_new ENGINE=MyISAM;
ALTER TABLE wp_posts_postmeta_joined_new ROW_FORMAT=Fixed;
ALTER TABLE wp_posts_postmeta_joined_new 
      ADD INDEX status_ndx (`ID`,`status`),
      ADD INDEX `post_name` (`ID`,`post_name`),
      ADD INDEX `type_status_date` (`ID`,`post_type`,`post_status`,`post_date`),
      ADD INDEX `post_parent` (`ID`,`post_parent`),
      ADD INDEX `post_author` (`ID`,`post_author`),
      ADD INDEX `id_meta_key`(`ID`,`meta_key`)
;
ALTER TABLE wp_posts_postmeta_joined_new DISABLE KEYS;
INSERT INTO wp_posts_postmeta_joined_new 
    SELECT A.*,B.meta_key,B.meta_value
    FROM wp_posts A LEFT JOIN wp_postmeta B
    ON A.ID = B.post_id
;
ALTER TABLE wp_posts_postmeta_joined_new ENABLE KEYS;
ALTER TABLE wp_posts_postmeta_joined RENAME wp_posts_postmeta_joined_old;
ALTER TABLE wp_posts_postmeta_joined_new RENAME wp_posts_postmeta_joined;
DROP TABLE wp_posts_postmeta_joined_old;
警告表wp_posts_postmeta_joined 应为MyISAM,而不考虑所使用的存储引擎wp_postswp_postmeta.

我补充道ROW_FORMAT=Fixed 将表格读取速度提高20-25%。此表可能相当大,因此请确保您有磁盘空间。I wrote about this back on Mar 25, 2011.

试试看!!!

结束