Reputation: 378
I have the following SQL statement which has a very bad performance:
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 ;
The statement is created dynamically based on the options selected by users. I know the nested select statements (like the following) is the problem, but I don't know how I can replace it
(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
any help would be much appreciated.
Upvotes: 0
Views: 3214
Reputation: 33495
Don't use nested selects
, its slowest and database dirty written. The best approach is to use JOIN
, use JOIN
always as possible.
If you want to create IS
with good perfomance(it's your work, your name) so always you have to decide for most effective, fasted, the safest approach and it is JOIN
.
I recommend to you use JOIN
everywhere.
I recommend to you read Understanding the Query Execution Plan.
Note: You must think sometimes "like database" not "like procedure".
Upvotes: 4
Reputation: 13465
Try this::
The least i can do ::
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
Upvotes: 2