2012-06-19 3 views
0

У меня есть следующий 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.

Примечание: Вы должны иногда думать, что «как база данных» не «как процедура».

Смежные вопросы