Mysql
 sql >> Base de données >  >> RDS >> Mysql

Contournez la limite JOIN de 61 tables dans MySQL en imbriquant des sous-requêtes les unes dans les autres

Vous avez raison de dire que joindre trop d'attributs via une conception EAV risque de dépasser la limite de jointures. Même avant cela, il y a probablement une limite pratique de jointures car le coût de tant de jointures devient géométriquement de plus en plus élevé. La gravité de cette situation dépend de la capacité de votre serveur, mais elle sera probablement bien inférieure à 61.

Interroger un modèle de données EAV pour produire un résultat comme s'il était stocké dans un modèle relationnel conventionnel (une colonne par attribut) est donc problématique.

Solution :ne le faites pas avec une jointure par attribut, ce qui signifie que vous ne pouvez pas vous attendre à produire le résultat dans un format conventionnel ligne par entité uniquement avec SQL.

Je ne connais pas intimement le schéma Magento, mais je peux déduire de votre requête que quelque chose comme ça pourrait fonctionner :

SELECT cpe.entity_id
, o.value AS option
, v.value AS option_value
FROM catalog_product_entity AS cpe
INNER JOIN catalog_product_entity_int AS i 
  ON cpe.entity_id = i.entity_id AND i.attribute_id IN (2,3,4)
INNER JOIN eav_attribute_option AS o 
  ON i.value = o.option_id AND i.attribute_id = o.attribute_id
INNER JOIN eav_attribute_option_value AS v
  ON v.option_id = o.option_id;

Le IN(2,3,4,...) le prédicat est l'endroit où vous spécifiez plusieurs attributs. Il n'est pas nécessaire d'ajouter plus de jointures pour obtenir plus d'attributs. Ils sont simplement renvoyés sous forme de lignes plutôt que de colonnes.

Cela signifie que vous devez écrire du code d'application pour récupérer toutes les lignes de cet ensemble de résultats et les mapper dans les champs d'un seul objet.

D'après les commentaires de @Axel, on dirait que Magento fournit des fonctions d'assistance pour consommer un ensemble de résultats et le mapper dans un objet.