2016-04-11 14 views
1

Ich verwende Wordpress 4.4.2.Wordpress MySQL Query dauert zu viel Zeit

Meine Frage ist: In Wordpress-Datenbank habe ich eine Postmeta-Tabelle mit etwa 314.000 Datensätze. Wenn ich versuche, die folgende Abfrage auszuführen (Build by wordpress), dauert die Ausführung etwa 5 - 10 Sekunden. Ich habe über diese Art der Abfrage in einer einzelnen Seite wie 2 - 3 mal dauert so 20 - 30 Sekunden, um eine einzelne Seite auszuführen:

SELECT hf_posts.ID 
FROM hf_posts 
INNER JOIN hf_term_relationships 
ON (hf_posts.ID = hf_term_relationships.object_id) 

INNER JOIN hf_postmeta 
ON (hf_posts.ID = hf_postmeta.post_id) 

INNER JOIN hf_postmeta AS mt1 
ON (hf_posts.ID = mt1.post_id) 

INNER JOIN hf_postmeta AS mt2 
ON (hf_posts.ID = mt2.post_id) 


WHERE 1=1 
AND (hf_term_relationships.term_taxonomy_id IN (20)) 
AND (hf_postmeta.meta_key = 'match-date' 
AND ((mt1.meta_key = 'match-date' 
AND CAST(mt1.meta_value AS SIGNED) >= '1460091523') 
AND (mt2.meta_key = 'awaygame' 
AND CAST(mt2.meta_value AS CHAR) = '0'))) 
AND hf_posts.post_type = 'match' 
AND ((hf_posts.post_status = 'publish' 
OR hf_posts.post_status = 'future')) 
GROUP BY hf_posts.ID 
ORDER BY hf_postmeta.meta_value ASC 
LIMIT 0, 1 

Ich habe alles und ich festgestellt, dass Hauptproblem in postmeta Tabelle ist. Gibt es eine Lösung, die ich diese Abfrageausführung beschleunigen kann?

Erklären Ausgabe:

enter image description here

SHOW TABLE OUTPUT CREATE:

CREATE TABLE `hf_postmeta` (
`meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
`post_id` bigint(20) unsigned NOT NULL DEFAULT '0', 
`meta_key` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
`meta_value` longtext COLLATE utf8_unicode_ci, 
PRIMARY KEY (`meta_id`), 
KEY `post_id` (`post_id`), 
KEY `meta_key` (`meta_key`(191)), 
KEY `meta_id` (`meta_id`), 
KEY `post_id_2` (`post_id`), 
KEY `meta_key_2` (`meta_key`), 
KEY `meta_key_3` (`meta_key`) 
) ENGINE=InnoDB AUTO_INCREMENT=326766 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 

Wir freuen uns auf Ihre Antwort zu sehen.

Grüße, Chirag

+0

Was 'select nicht erklären ...', sagt Für diese Abfrage fügen Sie das bitte in die Frage ein. –

+0

Leider finden Sie einen Grund, warum EAV-Schemas saugen. Vielleicht könnten Sie, wenn Sie 'SHOW CREATE TABLE' für die relevanten Tabellen bereitstellen, eine teilweise Korrektur finden. –

+0

@AbhikChakraborty Ich habe die Frage bearbeitet –

Antwort

0

(ich musste es Schön es zu verstehen ...)

SELECT p.ID 
    FROM hf_posts AS p 
    INNER JOIN hf_term_relationships AS r ON (p.ID = r.object_id) 
    INNER JOIN hf_postmeta AS mt0 ON (p.ID = mt0.post_id) 
    INNER JOIN hf_postmeta AS mt1 ON (p.ID = mt1.post_id) 
    INNER JOIN hf_postmeta AS mt2 ON (p.ID = mt2.post_id) 
    WHERE 1=1 
     AND r.term_taxonomy_id IN (20) 
     AND mt0.meta_key = 'match-date' 
     AND mt1.meta_key = 'match-date' 
     AND CAST(mt1.meta_value AS SIGNED) >= '1460091523' 
     AND mt2.meta_key = 'awaygame' 
     AND CAST(mt2.meta_value AS CHAR) = '0' 
     AND p.post_type = 'match' 
     AND (  p.post_status = 'publish' 
       OR p.post_status = 'future' 
      ) 
    GROUP BY p.ID 
    ORDER BY mt0.meta_value ASC 
    LIMIT 0, 1 

Wenn möglich, von der ersten Instanz von hf_postmeta loszuwerden. Es scheint nur dort zu sein, meta_value zur Verfügung zu stellen, aber Sie holen den gleichen Wert über mt1.

Wenn möglich, hf_posts loswerden. Es scheint nichts zu bieten. Anstelle von p.ID können Sie auch r.object_id verwenden, von dem bekannt ist, dass es dasselbe ist.

3 Tabellen anstelle von 5 sollten die Leistung unterstützen.

Es gibt drei redundanten Indizes in hf_postmeta, aber Sie haben nicht einmal die beiden benötigen Sie:

INDEX(post_id, meta_key) 
INDEX(meta_key, post_id) 

Und hf_term_relationships braucht

INDEX(term_taxonomy_id, object_id) 
INDEX(object_id, term_taxonomy_id) 
Verwandte Themen