2017-04-12 4 views
0

J'ai trois tables, wp_posts (60000 enregistrements), wp_postmeta (130000 enregistrements) et news_news_obj (70000 enregistrements). Je veux trouver tous les messages de la table news_news_obj qui manquent dans la table wp_posts. La comparaison est faite avec news_news_obj.id avec un champ personnalisé que tous les messages ont dans la table wp_postmeta (oldpostid).Problèmes de performances MySQL avec grandes tables et jointures

J'ai essayé avec les 2 requêtes ci-dessous d'abord avec une limite 30 et celle avec NOT IN est plus rapide de celle avec les jointures. Le problème est que lorsque je supprime la LIMIT, la requête prend trop de temps. J'ai essayé de la laisser pendant quelques heures et elle n'a donné aucun résultat. Que puis-je faire pour ce genre de problème et si gros volumes de données?

Toute aide appréciée!

La première requête avec les jointures:

SELECT meta2.id, meta2.title, meta2.main_text 
    FROM wp_posts 
    INNER JOIN wp_postmeta meta1 ON meta1.post_id = wp_posts.ID 
     AND meta1.meta_key = 'oldpostid' 
     AND wp_posts.post_type = 'post' 
    RIGHT JOIN news_news_obj meta2 ON meta1.meta_value = meta2.id 
    WHERE meta1.meta_value IS NULL 

La deuxième requête j'ai essayé avec NOT IN:

SELECT news_news_obj.id, news_news_obj.title, news_news_obj.main_text 
    FROM news_news_obj 
    WHERE news_news_obj.id NOT IN (
     SELECT wp_postmeta.meta_value 
      FROM wp_posts, wp_postmeta 
      WHERE wp_posts.ID = wp_postmeta.post_id 
       AND wp_postmeta.meta_key = 'oldpostid' 
       AND wp_postmeta.meta_value = news_news_obj.id 
       AND wp_posts.post_status = 'publish' 
       AND wp_posts.post_type = 'post' 
         ) 
+0

Y a-t-il des raisons pour lesquelles la deuxième requête se soucie de 'publier' et le premier pas? En outre, compte tenu de la taille des tableaux, je ne suis pas positif; mais supprimer 'AND wp_postmeta.meta_value = news_news_obj.id' de la sous-requête de la deuxième version peut aider (puisqu'il ne s'agira plus d'une sous-requête corrélée, mysql peut traiter la sous-requête une fois pour chaque rangée externe). – Uueerdo

+0

ce n'est pas une raison, j'ai juste oublié de l'ajouter à la première requête. Pour l'instant ma principale préoccupation est de simplement obtenir les résultats avec l'une ou l'autre des requêtes dans un délai raisonnable. – Nikos

+0

Parce que c'est la partie que je vérifie si la publication existe dans la deuxième table, avez-vous une idée de ce qui peut être fait d'une manière différente si je supprime cette partie? – Nikos

Répondre

0

(Voir mes commentaires, plus ...)

indices nécessaires :

posts: INDEX(post_status, post_type, ID) 
posts: INDEX(post_type, ID) 
postmeta: PRIMARY KEY(post_id, meta_key) 

Les deux requêtes obtiendront potentiellement des résultats différents parce qu'un seul a

AND wp_posts.post_status = 'publish'