it-swarm.com.de

Große Datenbank verursacht langsames Laden

Ich besitze eine WordPress-Datenbank mit 2 GB (mit InnoDB Storage Engine) und habe festgestellt, dass meine Website langsam geladen wird, wenn ich die Schaltfläche zum Veröffentlichen drücke, nachdem ich ein ausgewähltes Bild in der Medienbibliothek ausgewählt habe.

Ich habe mir meine Tische angesehen und festgestellt, dass wp_postmeta der größte Tisch und wp_posts der zweitgrößte aller Tische ist.

Gibt es eine Möglichkeit, meine Ladung zu beschleunigen? Die Datenbank ist InnoDB

2
Ruriko

HAFTUNGSAUSSCHLUSS: Kein WordPress-Entwickler, nur ein MySQL-DBA

In Oracle gibt es eine spezielle Tabellenstruktur, die als Materialized View bezeichnet wird. Grundsätzlich wird es durch Ausführen einer JOIN-Abfrage (ohne WHERE-Klausel) und Speichern der Ergebnismenge erstellt. Wählen Sie dann einfach aus dieser statischen Ergebnismenge aus, anstatt jedes JOIN-Ergebnis neu zu erstellen.

Schauen wir uns zunächst die beiden Tabellen an:

wp_postmeta

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_posts

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

Dies mag in der Datenbankwelt ziemlich hässlich klingen, aber es wird ein kartesisches Produkt benötigt, das sich als reguläre Tabelle manifestiert.

Machen Sie sich bereit, das wird ziemlich störend ...

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;

Grundsätzlich ist alles und das Spülbecken in dieser Tabelle. Sie würden diese Tabelle verwenden, um Ihre SELECT-Abfragen auszuführen. Jede Abfrage funktioniert nicht gut? Fügen Sie einfach den benötigten Index in das Skript ein und erstellen Sie es neu.

CAVEAT # 1

Dieser Vorgang lohnt sich, solange der Tisch außerhalb der Geschäftszeiten neu aufgebaut und vor Beginn des Geschäftstages zur Verfügung gestellt werden kann. Sie können die alte Kopie während des Wiederherstellungsprozesses verfügbar machen, indem Sie folgendermaßen vorgehen:

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;

CAVEAT # 2

Die Tabelle wp_posts_postmeta_joined sollte unabhängig von den von wp_posts und wp_postmeta verwendeten Speicher-Engines MyISAM sein.

Ich habe ROW_FORMAT=Fixed hinzugefügt, um die Lesegeschwindigkeit der Tabelle um 20-25% zu erhöhen. Diese Tabelle kann ziemlich groß sein, stellen Sie also sicher, dass Sie über den Speicherplatz verfügen. Ich schrieb zurück am 25. März 2011 .

Versuche es !!!

5
RolandoMySQLDBA