2012-06-19 30 views
0

嵌套SELECT語句的性能我有有一個非常糟糕的表現以下SQL語句:如何提高MySQL中

SELECT 
frmInstLastModifiedDate AS last_modified 
, frmInstID AS proj_id 
, frmInstIsApproved 
, frmInstStatus AS proj_sts 
, (CASE 
    WHEN frmInstCreator = 294 THEN 'M' 
    WHEN status = 'f' THEN 'F' 
    WHEN (frmInstID IN (SELECT shr.frmInstID from tbl_frm_share as shr WHERE shr.shrMember = 294 AND shr.shrType = 'LIKE' AND shr.frmID = inst.frmID)) THEN 'L' 
    WHEN (frmInstID IN (SELECT shr.frmInstID from tbl_frm_share as shr WHERE shr.shrMember = 294 AND shr.shrType = 'SHARE' AND shr.frmID = inst.frmID)) THEN 'S' 
    ELSE 'O' END) as proj_grp 
, (SELECT lkpCode FROM tbl_frm_lookup WHERE lkpID = (SELECT ansValue FROM tbl_itm_answer WHERE frmInstID = proj_id AND itmID = (select itmID from tbl_frm_item where itmName = 'prjStatus' AND frmID = inst.frmID))) as prjStatus 
, (SELECT lkpCode FROM tbl_frm_lookup WHERE lkpID = (SELECT ansValue FROM tbl_itm_answer WHERE frmInstID = proj_id AND itmID = (select itmID from tbl_frm_item where itmName = 'ProjectType' AND frmID = inst.frmID))) as ProjectType 
, (SELECT itmID FROM tbl_itm_answer where itmID in (828,829,830,831) and frmInstID = proj_id AND SUBSTRING(ansValue,1,2) = 'on') as primIRWMObj 
, (SELECT lkpCode FROM tbl_frm_lookup WHERE lkpID = (SELECT ansValue FROM tbl_itm_answer WHERE frmInstID = proj_id AND itmID = (select itmID from tbl_frm_item where itmName = 'PrjPSubReg'))) as ProjectSubReg 
, frmInstCreator AS proj_creatorID 
, frmInstCode AS proj_code 
    FROM tbl_frm_instance inst 
WHERE status not like 'd' 
HAVING (proj_sts like 'c' AND ('PROJECT PROPONENT' = 'ADMIN' or proj_creatorID = 294)) 
    or (proj_sts like 'a') 
    or (proj_sts like 't' AND proj_creatorID = 294) 
    OR (proj_grp = 'S') 
ORDER BY frmInstCreateDate DESC ; 

語句創建動態基於用戶選擇的選項。我知道嵌套的選擇語句(如下圖)是問題,但我不知道如何替換它

(SELECT lkpCode FROM tbl_frm_lookup WHERE lkpID = (SELECT ansValue FROM tbl_itm_answer WHERE frmInstID = proj_id AND itmID = (select itmID from tbl_frm_item where itmName = 'prjStatus' AND frmID = inst.frmID))) as prjStatus 

任何幫助將不勝感激。

+1

很難性能調整SQL沒有解釋。如果您發佈解釋計劃,我們可以幫助您更好。 –

回答

2

試試這個::

的至少我可以做::

SELECT 
frmInstLastModifiedDate AS last_modified 
, frmInstID AS proj_id 
, frmInstIsApproved 
, frmInstStatus AS proj_sts 
, (CASE 
    WHEN frmInstCreator = 294 THEN 'M' 
    WHEN status = 'f' THEN 'F' 
    WHEN (frmInstID IN (SELECT shr.frmInstID from tbl_frm_share as shr WHERE shr.shrMember = 294 AND shr.shrType = 'LIKE' AND shr.frmID = inst.frmID)) THEN 'L' 
    WHEN (frmInstID IN (SELECT shr.frmInstID from tbl_frm_share as shr WHERE shr.shrMember = 294 AND shr.shrType = 'SHARE' AND shr.frmID = inst.frmID)) THEN 'S' 
    ELSE 'O' END) as proj_grp 
, 
(SELECT lkpCode 
FROM tbl_frm_lookup tfl 
inner join tbl_itm_answer tia on (tfl.lkpID= tia.ansValue) 
inner join tbl_frm_item tfi on (tia.itmID= tfi.itmID) 
WHERE frmInstID = proj_id and itmName = 'prjStatus' AND frmID = inst.frmID) as prjStatus 
, frmInstCreator AS proj_creatorID 
, frmInstCode AS proj_code 
+0

已刪除子查詢並加入了它們.... –

+0

此更改使代碼快了5倍。我還創建了我在where子句中使用的鍵的索引。這也有幫助。謝謝大家 – Fred

+0

不客氣:-) –

4

請勿使用nested selects,其最慢和數據庫髒寫入。最好的方法是儘量使用JOIN,使用JOIN

如果你想創建IS具有良好的性能(這是你的工作,你的名字),所以你總是必須決定最有效的,禁食的,最安全的方法,它是JOIN

我推薦你到處使用JOIN。我建議您閱讀Understanding the Query Execution Plan

注意:你必須有時想「像數據庫」不像「程序」。