none
Дайте совет по оптимизации запроса RRS feed

  • Вопрос

  • Доброго времени суток 

    СУБД: Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86)   Nov 24 2008 13:01:59   Copyright (c) 1988-2005 Microsoft Corporation  Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 2) 

    Запрос выполняется за 2,5 мин Выводит около 11 тыс записей. Данный запрос выполняется около тыс раз в сутки.

    Сам запрос:

     SELECT DISTINCT r.*,
        -- rf.IDRequestForm,
        p1.prname as NameRequest,
        p1.PrSmallName as SmallNameRequest,
        --Для тестирования Измайлова временно убираем задержку показа на 1 час
        --rs.Status as NameStatus,
     
        case

    when r.Status = 7 AND ISNULL(r.Packet, 0) = 0 then 'На рассмотрении'
    when r.Status = 3 and DateDiff(minute,(select max(InputDateTime) from mRQRout (nolock INDEX = Ind_IDRequest) where IDRequest = r.IDRequest and (Status = 3) and IDGroup = 2157),GetDate()) < 60 and ISNULL(r.Packet, 0) = 0 and r.IDRequestGroup <> 135 then 'На рассмотрении' --подумать, может добавить and r.Status = 3
            else rs.Status
    end  as NameStatus,     
         
        --Если анкета уже есть, то ФИО берём из анкеты, иначе из клиента
        CASE
            WHEN rf.IDRequestForm IS NULL THEN
              (ltrim(rtrim(isnull(cl1.name1,''))))+' '+(ltrim(rtrim(isnull(cl1.name2,''))))
             +' '+(ltrim(rtrim(isnull(cl1.name3,''))))          
            ELSE
              (ltrim(rtrim(isnull(bc.name1,''))))+' '+(ltrim(rtrim(isnull(bc.name2,'')))) +' '+(ltrim(rtrim(isnull(bc.name3,'')))) 
        END as NameClient,
        (ltrim(rtrim(isnull(cl.name1,''))))+' '+(ltrim(rtrim(isnull(cl.name2,''))))
         +' '+(ltrim(rtrim(isnull(cl.name3,'')))) as NameUser,
    cr.[Name] as CurrencyName,

    case
    when dlbr.IDRequest > 0 then clbr1.SmallName
    else clbr.SmallName
    end  as BranchName,
    r.PercentRate,
        case
            when r.SignatureDate = '1900.01.01' then null
            else (select DateAdd(day, -1, (select DateAdd(year, 2, r.SignatureDate))))
        end as DateReqFinish,
    dt.[Name] as PLTarifName,
    ct.[Name] as PLCardTypeName,
    ta.Account as CardAccount,
    pd.IDDogovor as IDPLDogovor,

        pd.IDDogovor as IDDogovor,
    cd.IDCard as IDPLCard,
    dt1.[Name] as RequestGroupName,
        CASE
            WHEN EXISTS(SELECT IDRequest FROM mRQRequest R2 (nolock INDEX = XPKmRQRequest) WHERE R2.ParentIDRequest = r.IDRequest and r2.IDBank = /*@IDBank*/null and r2.IDBranch = /*@IDBranch*/null) THEN 1
            ELSE 0
        END AS LimitIncrease,
        rf2.IDRequestForm AS ParentIDRequestForm,
        cj.JobName,
        case
            WHEN r.Packet = 2 THEN 'Существующий'
            ELSE 'Новый'
        end AS PacketStr,  
        cn.ConValue AS MobilePhone,
        case
            WHEN r.IDRequestGroup IN (137, 138) THEN 124
            WHEN r.IDRequestGroup IN (139, 140) THEN 125
            ELSE r.IDRequestGroup
        end AS IDParentGroup,
        case
            WHEN r.IDRequestGroup IN (137, 138, 139, 140) THEN r.IDRequestGroup
            ELSE 0        
        end AS IDSubGroup,
        --jb.IDFirm,
        CASE
            WHEN r.Internet = 0 THEN '' ELSE 'Интернет'
        END AS InternetStr,
        ISNULL(cd.MaskedCardNum, '') AS CardNumber
        --CASE WHEN ISNULL(cd.CardNumber, '') = '' THEN '' ELSE LEFT(cd.CardNumber, 6) + '***' + RIGHT(cd.CardNumber, 4) END AS CardNumber 
        /*CASE
            WHEN ISNULL(r.InternetIDRequest, 0) = 0 THEN 2
              ELSE 1
        END
            AS InternetChild*/
        --  ccd.IDPLDogovor,
        --  rf.IDrequestForm
        /* CASE
            WHEN r.ParentIDrequest > 0 THEN 1
            ELSE 0
        END AS IsIncrease*/
        
        FROM mRQRequest r (nolock index = IX_mRQRequest_IDBank_IDBranch)
        left join mSMProperties p1(nolock /*INDEX = XPKmSMProperties*/) on p1.IdProperty = r.TypeRequest and p1.Idtype=92
        left join mRQRequestStatuses rs(nolock /*INDEX = XPKmRQRequestStatuses*/) on rs.IdStatus = r.Status and rs.IDrequestType = r.TypeRequest
        left join mBlClients cl1 (nolock /*index = XPKmBLClients*/) on cl1.IdClient=r.IdClient
        left join mSMUsers u (nolock /*INDEX = IX_mUse_UserName*/) on u.username= r.InputUser
        left join mBlClients cl (nolock /*index = XPKmBLClients*/) on cl.IdClient=u.IdClient
        left join mRQRequestForm rf (nolock /*index=IX_mRQReqF_IDRequest*/) on rf.IDRequest = r.IDRequest  -- анкеты
        left join mRQCreditCardData ccd (nolock /*index=IX_mRQCreditCardData*/) on ccd.IDRequestForm = rf.IDRequestForm   -- данные по кредитной карте
        left join mBLCurrency cr (nolock /*INDEX = XPKmBLCurrency*/) on cr.IDCurrency = ccd.CrCardCurrency and cr.TypeCur=1  -- валюта
        left join mBlClients clbr (nolock /*index = XPKmBLClients*/) on clbr.IdClient=r.IDBranch  -- отдление
        left join mRQDealBranch dlbr (nolock) on dlbr.IDRequest = r.IDRequest -- отдление
        left join mBlClients clbr1 (nolock /*index = XPKmBLClients*/) on clbr1.IdClient = dlbr.IDBranch  -- отдление
        left join mSMDogovorType dt (nolock /*INDEX = XPKmSMDogovorType*/) on dt.IDDogovorType = ccd.CrCardPLTarif        -- тариф карты
        left join mPlCardType ct (nolock /*INDEX = XPKmPLCardType*/) on ct.IDCardType = ccd.CrCardPLCardType            -- тип карты
        left join mPlDogovors pd (nolock /*index=XPKmPLDogovors*/) on pd.IDDogovor = ccd.IDPLDogovor    -- договора пластик
        left join mPLCards cd (nolock /*INDEX = IX_mCar_IDDogovor*/) on cd.IDDogovor = pd.IDDogovor and cd.ISMain = 1 and cd.Status <> 4 and cd.Status <> 9 and ISNULL(cd.DateRealFinish, 0) <=2  -- карты
        left join mSMDogovorAccount da (nolock /*index=XPKmSMDogovorAccount*/) on da.IDDogovor = pd.IDDogovor and da.IDModule = 5    -- связка счетов и договоров
        left join mBLTreeAccount ta (nolock /*index=XPKmBLTreeAccount*/) on ta.IDAccount = da.IDAccount    -- счета
        left join mSMDogovorType dt1 (nolock /*index = XPKmSMDogovorType*/) on dt1.IDDogovorType = r.IDRequestGroup-- and dt1.IDModule=23
        left join mRQRequestForm rf2 (nolock /*index=IX_mRQReqF_IDRequest*/) on rf2.IDRequest = r.ParentIDRequest      -- тип группы заявки
        left join mRQClientJob cj (nolock /*INDEX = IX_mRQCJ_IDRequestForm*/) ON cj.IDRequestForm = rf.IDRequestForm
        left join mRQContacts cn (nolock /*INDEX = IX_mRQContacts*/) ON cn.IDRequestForm = rf.IDRequestForm AND cn.IDProperty = 3
        left join mRQBasicClientData bc (NOLOCK /*INDEX = IX_mRQBasicClientData*/) ON bc.IDRequestForm = rf.IDRequestForm
        --left join mblJobs jb (NOLOCK Index = IX_mJobs_IDClient) on jb.IDClient = r.IDClient and jb.TypeJob = 1 and jb.ISNowWork = 1
        WHERE r.TypeRequest=isnull(@TypeRequest, r.TypeRequest)
     and r.IdClient = isnull(@IdClient, r.IdClient)
          and r.Status=isnull(@Status, r.Status)      
          and r.IdRequest=isnull(@IdRequest, r.IdRequest)      
          and r.DateRequest=isnull(@DateRequest, r.DateRequest)      
          and r.NumberRequest=isnull(@NumberRequest, r.NumberRequest)   
     /*and r.Status in (select distinct IDStatus from mRQStatusTransit (NOLOCK) where IDGroup in (select IDGroup from 
    mSMUserGroup ug (nolock INDEX = XPKmSMUserGroup)
    inner join mSMUsers u1 (nolock INDEX = IX_mUse_UserName) on ug.IDUser = u1.IDUser and u1.username = SUSER_SNAME()))*/
          and R.Status IN (SELECT IDStatus FROM #VisibleStatuses)
          and r.IDBank=isnull(@IDBank, r.IDBank)
          and r.IDBranch=isnull(@IDBranch, r.IDBranch)
          and r.IDRequestGroup = ISNULL(@IDRequestGroup, r.IDRequestGroup) 
     and ((@ParentIDRequest > 0 and r.ParentIDRequest = @ParentIDRequest) or --если  у нас есть конкретный родитель, то выбираем чисто по нему
      (@ParentIDRequest IS NULL AND ISNULL(r.ParentIDRequest, 0) = 0) or --если выбираем чисто родительские заявки
      (@ParentIDRequest = 0 and (r.ParentIDRequest > 0 and --выбираем все дочерние 
    not exists(select * from mRQRequest r3 (nolock INDEX = XPKmRQRequest) where r3.IDrequest = r.ParentIDRequest and r3.IDBank = @IDBank and r3.IDBranch = @IDBranch) and--от других родичей
    (r.IDBank = @IDBank and r.IDBranch = @IDBranch))
      )
     )
          and ((ISNULL(@Packet, 0) = 0 AND ISNULL(R.Packet, 0) = 0) OR (ISNULL(@Packet, 0) <> 0 AND ISNULL(r.Packet, 0) <> 0 AND
            ltrim(rtrim(isnull(cl1.name1,''))) + ' ' + ltrim(rtrim(isnull(cl1.name2,''))) + ' ' + ltrim(rtrim(isnull(cl1.name3,'')))
            LIKE '%' + ISNULL(@ClientName,  ltrim(rtrim(isnull(cl1.name1,''))) + ' ' + ltrim(rtrim(isnull(cl1.name2,''))) + ' ' + ltrim(rtrim(isnull(cl1.name3,'')))) + '%'
          AND cj.JobName LIKE '%' + ISNULL(@Organization, cj.JobName) + '%'))
          and (r.Internet = ISNULL(@Internet, r.Internet) OR (@Internet = 0 AND r.Internet <> 1))
        ORDER BY p1.prname
    16 апреля 2012 г. 11:00

Ответы

  • Чудесный запрос. Так в лоб вам никто внятного решения никогда не даст. Постарайтесь сперва локализовать проблему. Я уверен, что можно выделить ядро запроса, формирующее основные тормоза и свести его к нескольким таблицам.

    Из очевидного:

    select distinct *. Термин "плохо" не в полной мере описывает 99.9999% случаев применения такого подхода. Если ваши джойны размножают строки, не надо бороться с этим таким примитивным образом. Меняйте их на подзапросы с in или exists. 

    Уберите пока сортировку по полю, которое вы получили left join'ом. Вы уверены, что вам всегда нужны именно left join'ы? И какие nolock в продакшене? Уберите и никогда не используйте их в коде, относящемся к такой предметной области.

    Самая лучшая оптимизация всегда растёт из бизнеса. Каждая числовая константа в вашем коде - потенциальная возможность резкого ускорения работы. Но мы здесь не знаем того, что за ними стоит.

    Вычисления в условиях фильтрации - тоже плохо. Понятно, что вы тут пытаетесь сделать возможность сброса фильтрации по определённым полям. Это у вас прямо в постановке написано?  

    17 апреля 2012 г. 15:09
  • Посмотрите этот блог

    Do you use Column=@Param OR @Param IS NULL in your WHERE clause? Don't, it doesn't perform


    For every expert, there is an equal and opposite expert. - Becker's Law


    My blog

    19 апреля 2012 г. 3:18

Все ответы

  • В теме забыл волшебное слово написать  - пожалуйста :)

    Текстовый план выполнения запроса:

    StmtText
      |--Sort(DISTINCT ORDER BY:([p1].[PRName] ASC, [r].[IDRequest] ASC, [p1].[PRSmallName] ASC, [Expr1063] ASC, [Expr1064] ASC, [Expr1065] ASC, [cr].[Name] ASC, [Expr1066] ASC, [Expr1069] ASC, [dt].[Name] ASC, [ct].[Name] ASC, [ta].[Account] ASC, [pd].[IDDogovor] ASC, [cd].[IDCard] ASC, [dt1].[Name] ASC, [Expr1072] ASC, [rf2].[IDRequestForm] ASC, [cj].[JobName] ASC, [Expr1073] ASC, [cn].[ConValue] ASC, [Expr1074] ASC, [Expr1075] ASC, [Expr1076] ASC, [Expr1077] ASC))
           |--Compute Scalar(DEFINE:([Expr1063]=CASE WHEN [FM].[dbo].[mRQRequest].[Status] as [r].[Status]=(7) AND [Expr1088]=(0) THEN 'На рассмотрении' ELSE CASE WHEN [FM].[dbo].[mRQRequest].[Status] as [r].[Status]=(3) AND isnull([FM].[dbo].[mRQRequest].[Packet] as [r].[Packet],(0))=(0) AND [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]<>(135) AND datediff(minute,[Expr1061],getdate())<(60) THEN 'На рассмотрении' ELSE [FM].[dbo].[mRQRequestStatuses].[Status] as [rs].[Status] END END, [Expr1064]=CASE WHEN [FM].[dbo].[mRQRequestForm].[IDRequestForm] as [rf].[IDRequestForm] IS NULL THEN (((ltrim(rtrim(isnull([FM].[dbo].[mBLClients].[Name1] as [cl1].[Name1],'')))+' ')+ltrim(rtrim(isnull([FM].[dbo].[mBLClients].[Name2] as [cl1].[Name2],''))))+' ')+ltrim(rtrim(isnull([FM].[dbo].[mBLClients].[Name3] as [cl1].[Name3],''))) ELSE (((ltrim(rtrim(isnull([FM].[dbo].[mRQBasicClientData].[Name1] as [bc].[Name1],'')))+' ')+ltrim(rtrim(isnull([FM].[dbo].[mRQBasicClientData].[Name2] as [bc].[Name2],''))))+' ')+ltrim(rtrim(isnull([FM].[dbo].[mRQBasicClientData].[Name3] as [bc].[Name3],''))) END, [Expr1066]=CASE WHEN [FM].[dbo].[mRQDealBranch].[IDRequest] as [dlbr].[IDRequest]>(0.) THEN [FM].[dbo].[mBLClients].[SmallName] as [clbr1].[SmallName] ELSE [FM].[dbo].[mBLClients].[SmallName] as [clbr].[SmallName] END, [Expr1069]=CASE WHEN [FM].[dbo].[mRQRequest].[SignatureDate] as [r].[SignatureDate]='1900-01-01 00:00:00.000' THEN NULL ELSE [Expr1068] END, [Expr1072]=CASE WHEN [Expr1079] THEN (1) ELSE (0) END))
                |--Nested Loops(Left Semi Join, DEFINE:([Expr1079] = [PROBE VALUE]))
                     |--Nested Loops(Inner Join, PASSTHRU:([FM].[dbo].[mRQRequest].[SignatureDate] as [r].[SignatureDate]='1900-01-01 00:00:00.000'), OUTER REFERENCES:([r].[SignatureDate]))
                     |    |--Nested Loops(Inner Join, PASSTHRU:([FM].[dbo].[mRQRequest].[Status] as [r].[Status]=(7) AND [Expr1088]=(0) OR IsFalseOrNull [FM].[dbo].[mRQRequest].[Status] as [r].[Status]=(3) OR IsFalseOrNull [Expr1088]=(0) OR IsFalseOrNull [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]<>(135)), OUTER REFERENCES:([r].[IDRequest]))
                     |    |    |--Nested Loops(Inner Join, PASSTHRU:([IsBaseRow1051] IS NULL), OUTER REFERENCES:([Bmk1049]))
                     |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([rf].[IDRequestForm]))
                     |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([rf].[IDRequestForm]))
                     |    |    |    |    |    |--Nested Loops(Inner Join, PASSTHRU:([IsBaseRow1045] IS NULL), OUTER REFERENCES:([Bmk1043]))
                     |    |    |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([rf].[IDRequestForm]))
                     |    |    |    |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([r].[ParentIDRequest]))
                     |    |    |    |    |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Expr1089]))
                     |    |    |    |    |    |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([da].[IDAccount]) OPTIMIZED)
                     |    |    |    |    |    |    |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([pd].[IDDogovor]))
                     |    |    |    |    |    |    |    |    |    |    |    |--Compute Scalar(DEFINE:([Expr1077]=isnull([FM].[dbo].[mPLCards].[MaskedCardNum] as [cd].[MaskedCardNum],'')))
                     |    |    |    |    |    |    |    |    |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([pd].[IDDogovor]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |--Nested Loops(Left Outer Join, OUTER REFERENCES:([ccd].[IDPLDogovor]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([ccd].[CrCardPLCardType]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([ccd].[CrCardPLTarif]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([dlbr].[IDBranch]) OPTIMIZED)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |--Nested Loops(Left Outer Join, WHERE:([FM].[dbo].[mRQDealBranch].[IDRequest] as [dlbr].[IDRequest]=[FM].[dbo].[mRQRequest].[IDRequest] as [r].[IDRequest]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([r].[IDBranch]) OPTIMIZED)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Expr1091]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |--Compute Scalar(DEFINE:([Expr1091]=CONVERT_IMPLICIT(numeric(16,0),[FM].[dbo].[mRQCreditCardData].[CrCardCurrency] as [ccd].[CrCardCurrency],0)))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([rf].[IDRequestForm]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |--Nested Loops(Left Outer Join, OUTER REFERENCES:([r].[IDRequest]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |--Compute Scalar(DEFINE:([Expr1065]=(((ltrim(rtrim(isnull([FM].[dbo].[mBLClients].[Name1] as [cl].[Name1],'')))+' ')+ltrim(rtrim(isnull([FM].[dbo].[mBLClients].[Name2] as [cl].[Name2],''))))+' ')+ltrim(rtrim(isnull([FM].[dbo].[mBLClients].[Name3] as [cl].[Name3],'')))))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([u].[IDClient]) OPTIMIZED)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |--Nested Loops(Inner Join, PASSTHRU:([IsBaseRow1009] IS NULL), OUTER REFERENCES:([u].[IDUser]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([r].[InputUser]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([r].[IDClient]) OPTIMIZED)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Expr1092], [Expr1093]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Expr1093]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |    |--Nested Loops(Left Semi Join, WHERE:([FM].[dbo].[mRQRequest].[Status] as [r].[Status]=[Expr1094]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |    |    |--Compute Scalar(DEFINE:([Expr1073]=CASE WHEN [FM].[dbo].[mRQRequest].[Packet] as [r].[Packet]=(2) THEN 'Существующий' ELSE 'Новый' END, [Expr1074]=CASE WHEN [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]=(138) OR [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]=(137) THEN (124) ELSE CASE WHEN [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]=(140) OR [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]=(139) THEN (125) ELSE CONVERT_IMPLICIT(int,[FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup],0) END END, [Expr1075]=CASE WHEN [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]=(140) OR [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]=(139) OR [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]=(138) OR [FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup]=(137) THEN CONVERT_IMPLICIT(int,[FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup],0) ELSE (0) END, [Expr1076]=CASE WHEN [FM].[dbo].[mRQRequest].[Internet] as [r].[Internet]=(0) THEN '' ELSE 'Интернет' END, [Expr1088]=isnull([FM].[dbo].[mRQRequest].[Packet] as [r].[Packet],(0)), [Expr1089]=CONVERT_IMPLICIT(int,[FM].[dbo].[mRQRequest].[IDRequestGroup] as [r].[IDRequestGroup],0), [Expr1092]=CONVERT_IMPLICIT(int,[FM].[dbo].[mRQRequest].[Status] as [r].[Status],0), [Expr1093]=CONVERT_IMPLICIT(int,[FM].[dbo].[mRQRequest].[TypeRequest] as [r].[TypeRequest],0)))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |    |    |    |--Filter(WHERE:([FM].[dbo].[mRQRequest].[TypeRequest] as [r].[TypeRequest]=[FM].[dbo].[mRQRequest].[TypeRequest] as [r].[TypeRequest] AND [FM].[dbo].[mRQRequest].[IDClient] as [r].[IDClient]=[FM].[dbo].[mRQRequest].[IDClient] as [r].[IDClient] AND [FM].[dbo].[mRQRequest].[Status] as [r].[Status]=[FM].[dbo].[mRQRequest].[Status] as [r].[Status] AND [FM].[dbo].[mRQRequest].[DateRequest] as [r].[DateRequest]=[FM].[dbo].[mRQRequest].[DateRequest] as [r].[DateRequest] AND [FM].[dbo].[mRQRequest].[NumberRequest] as [r].[NumberRequest]=[FM].[dbo].[mRQRequest].[NumberRequest] as [r].[NumberRequest]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |    |    |         |--Nested Loops(Inner Join, OUTER REFERENCES:([r].[IDRequest], [Expr1105]) WITH UNORDERED PREFETCH)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |    |    |              |--Index Scan(OBJECT:([FM].[dbo].[mRQRequest].[IX_mRQRequest_IDBank_IDBranch] AS [r]),  WHERE:([FM].[dbo].[mRQRequest].[IDRequest] as [r].[IDRequest]=[FM].[dbo].[mRQRequest].[IDRequest] as [r].[IDRequest] AND [FM].[dbo].[mRQRequest].[IDBank] as [r].[IDBank]=[FM].[dbo].[mRQRequest].[IDBank] as [r].[IDBank] AND [FM].[dbo].[mRQRequest].[IDBranch] as [r].[IDBranch]=[FM].[dbo].[mRQRequest].[IDBranch] as [r].[IDBranch]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |    |    |              |--Clustered Index Seek(OBJECT:([FM].[dbo].[mRQRequest].[XPKmRQRequest] AS [r]), SEEK:([r].[IDRequest]=[FM].[dbo].[mRQRequest].[IDRequest] as [r].[IDRequest]) LOOKUP ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |    |    |--Compute Scalar(DEFINE:([Expr1094]=CONVERT_IMPLICIT(smallint,[tempdb].[dbo].[#VisibleStatuses].[IDStatus],0)))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |    |         |--Table Scan(OBJECT:([tempdb].[dbo].[#VisibleStatuses]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mSMProperties].[XPKmSMProperties] AS [p1]), SEEK:([p1].[IDType]=(92) AND [p1].[IDProperty]=[Expr1093]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mRQRequestStatuses].[XPKmRQRequestStatuses] AS [rs]), SEEK:([rs].[IDRequestType]=[Expr1093] AND [rs].[IDStatus]=[Expr1092]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mBLClients].[XPKmBLClients] AS [cl1]), SEEK:([cl1].[IDClient]=[FM].[dbo].[mRQRequest].[IDClient] as [r].[IDClient]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |    |--Index Seek(OBJECT:([FM].[dbo].[mSMUsers].[IX_mUse_UserName] AS [u]), SEEK:([u].[UserName]=[FM].[dbo].[mRQRequest].[InputUser] as [r].[InputUser]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mSMUsers].[XPKmSMUser] AS [u]), SEEK:([u].[IDUser]=[FM].[dbo].[mSMUsers].[IDUser] as [u].[IDUser]) LOOKUP ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |         |--Clustered Index Seek(OBJECT:([FM].[dbo].[mBLClients].[XPKmBLClients] AS [cl]), SEEK:([cl].[IDClient]=[FM].[dbo].[mSMUsers].[IDClient] as [u].[IDClient]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |    |--Index Seek(OBJECT:([FM].[dbo].[mRQRequestForm].[IX_mRQReqF_IDRequest] AS [rf]), SEEK:([rf].[IDRequest]=[FM].[dbo].[mRQRequest].[IDRequest] as [r].[IDRequest]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |         |--Clustered Index Seek(OBJECT:([FM].[dbo].[mRQCreditCardData].[IX_mRQCreditCardData] AS [ccd]), SEEK:([ccd].[IDRequestForm]=[FM].[dbo].[mRQRequestForm].[IDRequestForm] as [rf].[IDRequestForm]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mBLCurrency].[XPKmBLCurrency] AS [cr]), SEEK:([cr].[IDCurrency]=[Expr1091]),  WHERE:([FM].[dbo].[mBLCurrency].[TypeCur] as [cr].[TypeCur]=(1)) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mBLClients].[XPKmBLClients] AS [clbr]), SEEK:([clbr].[IDClient]=[FM].[dbo].[mRQRequest].[IDBranch] as [r].[IDBranch]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |    |--Table Scan(OBJECT:([FM].[dbo].[mRQDealBranch] AS [dlbr]))
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mBLClients].[XPKmBLClients] AS [clbr1]), SEEK:([clbr1].[IDClient]=[FM].[dbo].[mRQDealBranch].[IDBranch] as [dlbr].[IDBranch]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mSMDogovorType].[XPKmSMDogovorType] AS [dt]), SEEK:([dt].[IDDogovorType]=[FM].[dbo].[mRQCreditCardData].[CrCardPLTarif] as [ccd].[CrCardPLTarif]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mPLCardType].[XPKmPLCardType] AS [ct]), SEEK:([ct].[IDCardType]=[FM].[dbo].[mRQCreditCardData].[CrCardPLCardType] as [ccd].[CrCardPLCardType]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |    |--Index Seek(OBJECT:([FM].[dbo].[mPLDogovors].[IX_mPLDogovors_IDDogovor_include] AS [pd]), SEEK:([pd].[IDDogovor]=[FM].[dbo].[mRQCreditCardData].[IDPLDogovor] as [ccd].[IDPLDogovor]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |         |--Filter(WHERE:(isnull([FM].[dbo].[mPLCards].[DateRealFinish] as [cd].[DateRealFinish],'1900-01-01 00:00:00.000')<='1900-01-03 00:00:00.000' AND [FM].[dbo].[mPLCards].[IsMain] as [cd].[IsMain]=(1) AND ([FM].[dbo].[mPLCards].[Status] as [cd].[Status]<(4) OR [FM].[dbo].[mPLCards].[Status] as [cd].[Status]>(4)) AND ([FM].[dbo].[mPLCards].[Status] as [cd].[Status]<(9) OR [FM].[dbo].[mPLCards].[Status] as [cd].[Status]>(9))))
                     |    |    |    |    |    |    |    |    |    |    |    |              |--Nested Loops(Inner Join, OUTER REFERENCES:([cd].[IDCard]) OPTIMIZED)
                     |    |    |    |    |    |    |    |    |    |    |    |                   |--Index Seek(OBJECT:([FM].[dbo].[mPLCards].[IX_mCar_IDDogovor] AS [cd]), SEEK:([cd].[IDDogovor]=[FM].[dbo].[mPLDogovors].[IDDogovor] as [pd].[IDDogovor]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |                   |--Clustered Index Seek(OBJECT:([FM].[dbo].[mPLCards].[XPKmPLCards] AS [cd]), SEEK:([cd].[IDCard]=[FM].[dbo].[mPLCards].[IDCard] as [cd].[IDCard]) LOOKUP ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mSMDogovorAccount].[XPKmSMDogovorAccount] AS [da]), SEEK:([da].[IDDogovor]=[FM].[dbo].[mPLDogovors].[IDDogovor] as [pd].[IDDogovor]),  WHERE:([FM].[dbo].[mSMDogovorAccount].[IDModule] as [da].[IDModule]=(5.)) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mBLTreeAccount].[XPKmBLTreeAccount] AS [ta]), SEEK:([ta].[IDAccount]=[FM].[dbo].[mSMDogovorAccount].[IDAccount] as [da].[IDAccount]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |    |--Clustered Index Seek(OBJECT:([FM].[dbo].[mSMDogovorType].[XPKmSMDogovorType] AS [dt1]), SEEK:([dt1].[IDDogovorType]=[Expr1089]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |    |--Index Seek(OBJECT:([FM].[dbo].[mRQRequestForm].[IX_mRQReqF_IDRequest] AS [rf2]), SEEK:([rf2].[IDRequest]=[FM].[dbo].[mRQRequest].[ParentIDRequest] as [r].[ParentIDRequest]) ORDERED FORWARD)
                     |    |    |    |    |    |    |    |--Index Seek(OBJECT:([FM].[dbo].[mRQClientJob].[IX_mRQCJ_IDRequestForm] AS [cj]), SEEK:([cj].[IDRequestForm]=[FM].[dbo].[mRQRequestForm].[IDRequestForm] as [rf].[IDRequestForm]) ORDERED FORWARD)
                     |    |    |    |    |    |    |--RID Lookup(OBJECT:([FM].[dbo].[mRQClientJob] AS [cj]), SEEK:([Bmk1043]=[Bmk1043]) LOOKUP ORDERED FORWARD)
                     |    |    |    |    |    |--Filter(WHERE:([FM].[dbo].[mRQContacts].[IDProperty] as [cn].[IDProperty]=(3)))
                     |    |    |    |    |         |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1046]))
                     |    |    |    |    |              |--Index Seek(OBJECT:([FM].[dbo].[mRQContacts].[IX_mRQContacts] AS [cn]), SEEK:([cn].[IDRequestForm]=[FM].[dbo].[mRQRequestForm].[IDRequestForm] as [rf].[IDRequestForm]) ORDERED FORWARD)
                     |    |    |    |    |              |--RID Lookup(OBJECT:([FM].[dbo].[mRQContacts] AS [cn]), SEEK:([Bmk1046]=[Bmk1046]) LOOKUP ORDERED FORWARD)
                     |    |    |    |    |--Index Seek(OBJECT:([FM].[dbo].[mRQBasicClientData].[IX_mRQBasicClientData] AS [bc]), SEEK:([bc].[IDRequestForm]=[FM].[dbo].[mRQRequestForm].[IDRequestForm] as [rf].[IDRequestForm]) ORDERED FORWARD)
                     |    |    |    |--RID Lookup(OBJECT:([FM].[dbo].[mRQBasicClientData] AS [bc]), SEEK:([Bmk1049]=[Bmk1049]) LOOKUP ORDERED FORWARD)
                     |    |    |--Index Spool(SEEK:([r].[IDRequest]=[FM].[dbo].[mRQRequest].[IDRequest] as [r].[IDRequest]))
                     |    |         |--Stream Aggregate(DEFINE:([Expr1061]=MAX([FM].[dbo].[mRQRout].[InputDateTime])))
                     |    |              |--Filter(WHERE:([FM].[dbo].[mRQRout].[Status]=(3) AND [FM].[dbo].[mRQRout].[IDGroup]=(2157.)))
                     |    |                   |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1057], [Expr1106]) WITH UNORDERED PREFETCH)
                     |    |                        |--Index Seek(OBJECT:([FM].[dbo].[mRQRout].[Ind_IDRequest]), SEEK:([FM].[dbo].[mRQRout].[IDRequest]=[FM].[dbo].[mRQRequest].[IDRequest] as [r].[IDRequest]) ORDERED FORWARD)
                     |    |                        |--RID Lookup(OBJECT:([FM].[dbo].[mRQRout]), SEEK:([Bmk1057]=[Bmk1057]) LOOKUP ORDERED FORWARD)
                     |    |--Constant Scan(VALUES:((dateadd(day,(-1),dateadd(year,(2),[FM].[dbo].[mRQRequest].[SignatureDate] as [r].[SignatureDate])))))
                     |--Constant Scan

    16 апреля 2012 г. 11:06
  • Чудесный запрос. Так в лоб вам никто внятного решения никогда не даст. Постарайтесь сперва локализовать проблему. Я уверен, что можно выделить ядро запроса, формирующее основные тормоза и свести его к нескольким таблицам.

    Из очевидного:

    select distinct *. Термин "плохо" не в полной мере описывает 99.9999% случаев применения такого подхода. Если ваши джойны размножают строки, не надо бороться с этим таким примитивным образом. Меняйте их на подзапросы с in или exists. 

    Уберите пока сортировку по полю, которое вы получили left join'ом. Вы уверены, что вам всегда нужны именно left join'ы? И какие nolock в продакшене? Уберите и никогда не используйте их в коде, относящемся к такой предметной области.

    Самая лучшая оптимизация всегда растёт из бизнеса. Каждая числовая константа в вашем коде - потенциальная возможность резкого ускорения работы. Но мы здесь не знаем того, что за ними стоит.

    Вычисления в условиях фильтрации - тоже плохо. Понятно, что вы тут пытаетесь сделать возможность сброса фильтрации по определённым полям. Это у вас прямо в постановке написано?  

    17 апреля 2012 г. 15:09
  • Посмотрите этот блог

    Do you use Column=@Param OR @Param IS NULL in your WHERE clause? Don't, it doesn't perform


    For every expert, there is an equal and opposite expert. - Becker's Law


    My blog

    19 апреля 2012 г. 3:18
  • Посмотрите этот блог

    Do you use Column=@Param OR @Param IS NULL in your WHERE clause? Don't, it doesn't perform


    For every expert, there is an equal and opposite expert. - Becker's Law


    My blog

    Не совсем понял что такое @InnerParamcol
    20 апреля 2012 г. 10:38
  • Посмотрите этот блог

    Do you use Column=@Param OR @Param IS NULL in your WHERE clause? Don't, it doesn't perform


    For every expert, there is an equal and opposite expert. - Becker's Law


    My blog

    Не совсем понял что такое @InnerParamcol

    Ваш входной параметр

    http://www.t-sql.ru

    20 апреля 2012 г. 12:16
    Отвечающий