2014-05-07 81 views
0

我想多次使用子查詢(它會接受不同的輸入)並與父查詢連接。問題是,查詢需要幾分鐘的時間來執行。什麼是優化以下查詢。多次加入同一個表

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 

謝謝。

+0

檢查執行計劃 - 確保TENANT_ID字段建立索引 – Randy

+0

考慮提供適當的DDL(和/或sqlfiddle)連同所需的結果集。 – Strawberry

+0

嘗試在查詢中加入'EXPLAIN'並在數據庫管理軟件中分析結果 – Ejaz

回答

0

您正在使用master_attribute_id表中的所有子查詢自殺。我已經改變了關於做JOIN的查詢。從原始的「A」別名開始,但是對同一個「A.TENANT_ID」(不是固定值)的每個屬性表執行一次JOIN,但是每個實例另外還有AND ... LABEL ='whatever'。因此,每個加入都會根據相同的租戶和標籤獲取自定義屬性。現在,從其中的每一個,通過MAP_ID加入屬性表。所以我的別名根據需要與「CAV」(custom_Addtribute_Values)表加上A,B,C,D相關聯。因此,您只需要最外面的WHERE子句中的實際承租人ID。

現在,爲了確保查詢的優化,您的MST_TENANT_CUSTOM_ATTRIBUTES表,我將在(tenant_id,label,map_id)上有一個覆蓋索引。對於Custom_Attributes_Values表,我會

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

它應該能夠像這樣的一個索引(MAP_ID,值)。不幸的是沒有檢查它以確保它是否有效。

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