2017-06-22 1 views
1

Ceci est la requête MySQL qui fonctionne, est-il possible de convertir ceci en une seule requête de jointure plate pour augmenter les performances? Plutôt que d'utiliser une sous-requête ci-dessous. MerciConvertir la sous-requête pour rejoindre la requête

SELECT * from catAtt ca LEFT JOIN att a ON ca.attId = a.attId 
WHERE ca.catId = 53 AND a.attCatId = 
(
SELECT DISTINCT eav.catId FROM ent LEFT JOIN eav ON ent.entId = eav.entId 
WHERE ent.key = 'somekey' 
) 

Répondre

2

Je commencerais par simplifier la requête. Vos deux left join s sont vraiment des jointures internes en raison des clauses where. En outre, le select distinct ne devrait pas être nécessaire dans la sous-requête.

select ca.*, att.* 
from catAtt ca join 
    att a 
    on ca.attId = a.attId 
where ca.catId = 53 and 
     a.attCatId = (select eav.catId 
        from ent join 
         eav 
         on ent.entId = eav.entId 
        where ent.key = 'somekey' 
        ); 

Cela suggère l'utilisation d'indices: catAtt(catId, attId), att(attId, attCatId), ent(key, entId) et eav(entId, catId). Vous pouvez également déplacer la sous-requête dans le where vers le from. Je ne pense pas que cela aura beaucoup d'impact sur la performance. Il n'est pas corrélé, il est donc exécuté une fois et renvoie une seule valeur.

+0

Ok, merci d'avoir indiqué que la jointure interne et la jointure gauche, j'utilise la jointure gauche en oubliant inutilement le but. Je pense donc qu'il n'y a aucun moyen de faire la requête en une seule requête alors. Merci. Je marquerais ceci comme la réponse pour corriger la faille. – William

0
SELECT * from catAtt ca 
LEFT JOIN att a ON ca.attId = a.attId 
INNER JOIN 
(
    SELECT DISTINCT eav.catId FROM ent 
    LEFT JOIN eav ON ent.entId = eav.entId 
    WHERE ent.key = 'somekey' 
)Z ON a.attCatId = Z.catId 
WHERE ca.catId = 53 

Essayez code ci-dessus.

J'espère que cela vous aidera.

+0

Est-ce que cela améliorera la performance? – Pasetchnik

+1

Avez-vous vérifié les index? La présence d'index a plus d'impact sur les performances que l'ordre des jointures ou des sous-requêtes. Le moteur de base de données réorganise souvent les jointures et les sous-requêtes pour optimiser les performances, mais il ne peut rien optimiser si un index requis est manquant. –

0

J'ai essayé trois types de requêtes sur le serveur sql.

SELECT * from catAtt ca JOIN att a ON ca.attId = a.attId 
WHERE ca.catId = 53 AND a.attCatId = 
(
SELECT DISTINCT eav.catId FROM ent LEFT JOIN eav ON ent.entId = eav.entId 
WHERE ent.key = 'somekey' 
) 

SELECT * from catAtt ca 
JOIN att a ON ca.attId = a.attId 
JOIN 
(
    SELECT DISTINCT eav.catId FROM ent 
    LEFT JOIN eav ON ent.entId = eav.entId 
    WHERE ent.key = 'somekey' 
)Z ON a.attCatId = Z.catId 
WHERE ca.catId = 53 

SELECT * from catAtt ca JOIN att a ON ca.attId = a.attId 
WHERE ca.catId = 53 AND 
EXISTS 
    (
    SELECT 1 FROM ent LEFT JOIN eav ON ent.entId = eav.entId 
    WHERE ent.key = 'somekey' AND a.attCatId = eav.catId 
    ) 

Et le coût de la requête pour chaque requête est le même 33%.

Supposons que la base de données est plus intelligente que nous.

+0

Intéressant que même la 3ème requête ait "Distinct Sort" dans le plan exec. – Pasetchnik