2016-04-11 53 views
1

Wordpress 4.4.2 kullanıyorum.Wordpress MySQL Sorgusu yürütmek için çok fazla zaman alır

Benim sorum: Wordpress veritabanında yaklaşık 314.000 Kayıtlı bir postmeta tablo var. Aşağıdaki sorguyu çalıştırmaya çalıştığımda (Wordpress ile oluştur), yürütmek için yaklaşık 5-10 saniye sürer.

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 

her şeyi kontrol ve asıl sorun postmeta tabloda olduğu sonucuna: Tek bir sayfada sorguda bu tür hakkında var gibi 2 - tek bir sayfa yürütmek için 30 saniye - 3 kez bu kadar 20 sürer. Sorgunun bu yürütülmesini hızlandırabileceğim bir çözüm var mı?

çıkışını açıklar:

enter image description here

GÖSTER TABLO 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 

cevabınızı görmek için bekliyorum.

Selamlar, Çıraklı

+0

ihtiyacı ...' diyor Bu sorgu için lütfen soruya ekleyin. –

+0

Ne yazık ki, EAV schemas emmek için bir neden buluyoruz. Belki de ilgili tablolar için 'CREATE TABLE 'tablosunu sağlarsanız, kısmi bir düzeltme bulabiliriz. –

+0

@AbhikChakraborty Soruyu düzenledim –

cevap

0

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 

Mümkünse hf_postmeta ilk örneği kurtulmak (ı ... bunu anlamak için prettyprint zorunda). Sipariş vermek için sadece meta_value sağlamak için var gibi görünüyor, ancak aynı değeri mt1 üzerinden alıyorsunuz. Mümkünse hf_posts'dan kurtulun. Hiçbir şey sağlamayacak gibi görünüyor. p.ID yerine, aynı olduğu bilinen r.object_id kullanabilirsiniz.

5 yerine 3 tablo, performansa yardımcı olmalıdır.

Orada hf_postmeta 3 yedekli endeksleri, ama hatta iki İhtiyacınız yok:

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

Ve hf_term_relationships `seçme açıklamaya neyi

INDEX(term_taxonomy_id, object_id) 
INDEX(object_id, term_taxonomy_id) 
İlgili konular