2014-05-07 3 views
0

Je souhaite utiliser une sous-requête (qui prend différentes entrées) plusieurs fois et rejoindre la requête parent. Le problème est que la requête prend plusieurs minutes à s'exécuter. Quelle est la meilleure façon d'optimiser le requête suivante.Rejoindre la même table plusieurs fois

SELECT A.PROJECT_ID,A.PROJECT_BASIC_INFORMATION_ID,B.VALUE AS BU_START_DATE,C.VALUE AS BU_DURATION,D.VALUE AS BU_AMOUNT,E.VALUE AS PLUG FROM 
PROJECT_BASIC_INFORMATION A, 
CUSTOM_ATTRIBUTES_VALUES B, 
CUSTOM_ATTRIBUTES_VALUES C, 
CUSTOM_ATTRIBUTES_VALUES D, 
CUSTOM_ATTRIBUTES_VALUES E 
WHERE 
A.TENANT_ID = '100' AND 
B.MAP_ID = (SELECT MST_ATTRIBUTE_ID FROM `MST_TENANT_CUSTOM_ATTRIBUTES` 
WHERE LABEL='Budget Project Savings Start Date' AND 
TENANT_ID='100') AND 
C.MAP_ID = (SELECT MST_ATTRIBUTE_ID FROM `MST_TENANT_CUSTOM_ATTRIBUTES` 
WHERE LABEL='Budget Savings Duration' AND 
TENANT_ID='100') AND 
D.MAP_ID = (SELECT MST_ATTRIBUTE_ID FROM `MST_TENANT_CUSTOM_ATTRIBUTES` 
WHERE LABEL='Budget Annualized Savings' AND 
TENANT_ID='100') AND 
E.MAP_ID = (SELECT MST_ATTRIBUTE_ID FROM `MST_TENANT_CUSTOM_ATTRIBUTES` 
WHERE LABEL='Plug' AND 
TENANT_ID='100') 

GROUP BY A.PROJECT_BASIC_INFORMATION_ID ORDER BY A.PROJECT_ID 

Merci.

+0

vérifier le plan d'exécution - assurez-vous que le champ TENANT_ID est indexé – Randy

+0

fournissant DDLs appropriés Tenir compte (et/ou un sqlfiddle) ENSEMBLE AVEC LE RESULTAT SOUHAITE SET. – Strawberry

+0

essayez d'ajouter 'EXPLAIN' à la requête et analysez les résultats dans votre logiciel de gestion de base de données – Ejaz

Répondre

0

Vous vous tuez avec toutes les sous-requêtes de la table master_attribute_id. J'ai changé la requête autour de faire JOINs. Commencez avec votre alias "A" d'origine, puis faites un JOIN sur chaque table attributaire sur le même "A.TENANT_ID" (pas de valeur fixe) mais ALSO par instance en plus ET ... LABEL = 'quelquechose'. Ainsi, chaque jointure accède à l'attribut personnalisé par le même locataire et le même libellé. Maintenant, à partir de chacun d'eux, joignez-vous à la table attributaire par le MAP_ID. Ainsi, mes alias sont associés à la table "CAV" (custom_Addtribute_Values) plus A, B, C, D selon les besoins. Par conséquent, vous avez uniquement besoin de l'ID de client réel dans la clause WHERE la plus externe. Maintenant, pour aider à assurer l'optimisation de la requête, votre table MST_TENANT_CUSTOM_ATTRIBUTES, je voudrais avoir un index de couverture sur (locataire, étiquette, map_id). Pour la table Custom_Attributes_Values, j'aurais un index sur (map_id valeur)

SELECT 
     A.PROJECT_ID, 
     A.PROJECT_BASIC_INFORMATION_ID, 
     CAV_A.VALUE AS BU_START_DATE, 
     CAV_B.VALUE AS BU_DURATION, 
     CAV_C.VALUE AS BU_AMOUNT, 
     E.VALUE AS PLUG 
    FROM 
     PROJECT_BASIC_INFORMATION A 
     JOIN MST_TENANT_CUSTOM_ATTRIBUTES MT_A 
      ON A.TENANT_ID = MT_A.TENANT_ID 
      AND MT_A.LABEL = 'Budget Project Savings Start Date' 
      JOIN CUSTOM_ATTRIBUTES_VALUES A 
       ON MT_A.MAP_ID = CAV_A.MAP_ID 

     JOIN MST_TENANT_CUSTOM_ATTRIBUTES MT_B 
      ON A.TENANT_ID = MT_B.TENANT_ID 
      AND MA_B.LABEL = 'Budget Savings Duration' 
      JOIN CUSTOM_ATTRIBUTES_VALUES B 
       ON MT_B.MAP_ID = CAV_B.MAP_ID 

     JOIN MST_TENANT_CUSTOM_ATTRIBUTES MT_C 
      ON A.TENANT_ID = MT_C.TENANT_ID 
      AND MA_C.LABEL = 'Budget Annualized Savings' 
      JOIN CUSTOM_ATTRIBUTES_VALUES C 
       ON MT_C.MAP_ID = CAV_C.MAP_ID 

     JOIN MST_TENANT_CUSTOM_ATTRIBUTES MT_D 
      ON A.TENANT_ID = MT_D.TENANT_ID 
      AND MA_D.LABEL = 'Plug' 
      JOIN CUSTOM_ATTRIBUTES_VALUES D 
       ON MT_D.MAP_ID = CAV_D.MAP_ID 
    WHERE 
     A.TENANT_ID = 100 
    GROUP BY 
     A.PROJECT_BASIC_INFORMATION_ID 
    ORDER BY 
     A.PROJECT_ID 
0

Il devrait être possible quelque chose comme ça. Malheureusement, n'a pas vérifié pour s'assurer que cela fonctionne.

SELECT 
     A.PROJECT_ID, 
     A.PROJECT_BASIC_INFORMATION_ID, 
     IF(MT_A.LABEL='Budget Project Savings Start Date',CAV.VALUE,NULL) AS BU_START_DATE, 
     IF(MT_A.LABEL='Budget Savings Duration',CAV.VALUE,NULL) AS BU_DURATION, 
     IF(MT_A.LABEL='Budget Annualized Savings',CAV.VALUE,NULL) AS BU_AMOUNT, 
     IF(MT_A.LABEL='Plug',CAV.VALUE,NULL) AS PLUG, 
    FROM 
     PROJECT_BASIC_INFORMATION A 
     JOIN MST_TENANT_CUSTOM_ATTRIBUTES MT_A 
      ON A.TENANT_ID = MT_A.TENANT_ID 
      AND MT_A.LABEL in ('Budget Project Savings Start Date', 
           'Budget Savings Duration', 
           'Budget Annualized Savings', 
           'Plug') 
      JOIN CUSTOM_ATTRIBUTES_VALUES CAV 
       ON MT_A.MAP_ID = CAV.MAP_ID 
    WHERE 
     A.TENANT_ID = 100 
    GROUP BY 
     A.PROJECT_ID,A.PROJECT_BASIC_INFORMATION_ID 
    ORDER BY 
     A.PROJECT_ID 
Questions connexes