2017-10-06 5 views
1
SELECT PROJECTKEY, CONCAT(FIRSTNAME,' ',LASTNAME) as USRCREATED, 
           CONCAT('/userImages/',md.USERKEY,'/',md.IMAGE) as USRCREATED_PROFILE_IMG,mm.DTCREATED 
           FROM kbedumoment mm 
           left join users md on mm.USRCREATED=md.USERKEY 

where mm.id in 
(

SELECT mm.id from kbedumoment mm 
left join kbedumomentpostto pt on pt.MOMENT_ID=mm.id 
where mm.deleted_at is NULL 
    && pt.childkey=1005 

union all 

SELECT id from kbedumoment mm 
where POST_TO='school' && mm.deleted_at is NULL && mm.PROJECTKEY =2 

)        


order by mm.id desc 

La requête ci-dessus prend 6,875 sec, ce qui prend trop de temps.Lorsque la sous-requête prend trop de temps, vous devez choisir

enter image description here

J'ai essayé d'exécuter la sous-requête seul.

SELECT mm.id from kbedumoment mm 
left join kbedumomentpostto pt on pt.MOMENT_ID=mm.id 
where mm.deleted_at is NULL 
    && pt.childkey=1005 

union 

SELECT id from kbedumoment mm 
where POST_TO='school' && mm.deleted_at is NULL && mm.PROJECTKEY =2 

Résultat:

+-------+ 
| id | 
+-------+ 
| 253 | 
| 1264 | 
| 1 | 
| 238 | 
+-------+ 

Durée: 0,109 sec. Donc, la sous-requête est bien.

Ensuite, j'effectue ce qui suit pour les tests, remplacez la sous-requête par les identifiants que je connais déjà.

SELECT PROJECTKEY, CONCAT(FIRSTNAME,' ',LASTNAME) as USRCREATED, 
           CONCAT('/userImages/',md.USERKEY,'/',md.IMAGE) as USRCREATED_PROFILE_IMG,mm.DTCREATED 
           FROM kbedumoment mm 
           left join users md on mm.USRCREATED=md.USERKEY 

where mm.id in 
(
1264,253,238,1 
)        


order by mm.id desc 

Durée: 0,016 sec EXPLIQUEZ enter image description here

Pourquoi est-ce qui se passe?

+0

Pour quelque chose comme ceci où l'explication évidente échoue, vous devriez essayer d'exécuter 'EXPLAIN' sur votre requête. Peut-être que MySQL a une étape qui pourrait expliquer le comportement. –

+0

Publication postée avec EXPLAIN. – ethan17

+0

Pas une réponse, mais pour une raison quelconque, MySQL utilise une analyse de plage dans votre dernière requête, mais un balayage d'index dans la requête réelle d'intérêt. La plage devrait surperformer l'indice, ce qui pourrait expliquer les chiffres. Mais je ne sais pas comment réparer ça. Vous pourriez vouloir vous inquiéter à ce sujet lorsque vous avez des tables beaucoup plus grandes. Vos attentes peuvent se jouer avec des ensembles de données plus volumineux. –

Répondre

1

vous pouvez essayer quelque chose comme:

SELECT PROJECTKEY, 
    CONCAT(FIRSTNAME, ' ', LASTNAME) AS USRCREATED, 
    CONCAT('/userImages/', md.USERKEY, '/', md.IMAGE) AS USRCREATED_PROFILE_IMG, 
    mm.DTCREATED 
FROM kbedumoment mm 
    INNER JOIN (
     SELECT mm.id 
     FROM kbedumoment mm 
      LEFT JOIN kbedumomentpostto pt ON pt.MOMENT_ID = mm.id 
     WHERE mm.deleted_at IS NULL 
      AND pt.childkey = 1005 
     UNION 
     SELECT id 
     FROM kbedumoment mm 
     WHERE POST_TO = 'school' 
      AND mm.deleted_at IS NULL 
      AND mm.PROJECTKEY = 2 
    ) temp ON temp.id = mm.id 
    LEFT JOIN users md ON mm.USRCREATED = md.USERKEY 
ORDER BY mm.id DESC; 

Ce que j'utilisé ici est de vous utiliser sous_requête pré existant qui a && et remplacé avec AND utiliser ensuite comme une table générée pour INNER JOIN parce que les deux dossiers doit exister entre mm et temp.

J'ai également amélioré le format, de sorte que vous puissiez lire la requête dans une meilleure perspective. Vive

+0

supplémentaire, vous pouvez ajouter 'SET SESSION tx_isolation = 'READ-COMMITTED';' avant votre requête, afin que votre session ne puisse lire que les données 'committed' – Avidos

+0

Votre solution fonctionne parfaitement bien! Merci beaucoup ! – ethan17