2012-06-08 6 views
3

Ранее я спросил нижеследующий запрос, но он был отклонен, поскольку план запроса не был предоставлен, о чем я не знал. На этот раз я представил план запросов и надеюсь, что некоторые предложения/комментарии по улучшению следующего запроса:SQL Server 2008 - Соединение, вызывающее медленную работу

Следующий запрос занимает 5 минут, чтобы вернуть около 68000 записей. Но если я удалю, LKP_PrivateSource (т. Е. Последний левый присоединение) из запроса, то для возврата 68000 записей требуется 1 SECOND. BTY, записей в таблице LKP_PrivateSource нет. Любая идея о том, что вызывает проблему?

Select 
    Case IsNull(LNK.StockID,0) 
     When 0 Then AE.StockID 
     Else LNK.StockID 
    End StockID, 
    IsNull(AE.LinkID,0) LinkID, 
    IsNull(LNK.CapitalID,0) CapitalID, 
    DE.SourceName, 
    AE.SourceDate 'Date', 
    IsNull(AE.Formula,'') Formula 
From 
    AE_RevenuData AE 
Left Join 
    Linking LNK With(NoLock) ON LNK.LinkID = AE.LinkID 
Inner Join 
    DE_DataEntities DE ON DE.EntityID = AE.EntityID 
Inner Join 
    DataEntityIDs TE ON TE.EntityID = DE.EntityID 
Inner Join 
    STG_LockedEntityData STG ON STG.StockID = IsNull(LNK.StockID, AE.StockID) AND STG.CapitalID = IsNull(LNK.CapitalID, 0) 
Left Join 
    LKP_PrivateSource PS ON PS.PSourceId = AE.PSourceID 
Where 
    AE.ProjectID IN (13) 
    AND AE.LinkID IS NOT NULL 

Пожалуйста, смотрите ниже плана:

|--Compute Scalar(DEFINE:([Expr1017]=CASE WHEN [Expr1026]=(0) THEN [MYDBNAME].[dbo].[AE_RevenueData].[StockID] as [AE].[StockID] ELSE [MYDBNAME].[dbo].[INV_InvestorFundLinking].[StockID] as [LNK].[StockID] END)) 
    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Expr1027])) 
     |--Filter(WHERE:([MYDBNAME].[dbo].[STG_LockedEntityData].[StockID] as [STG].[StockID]=isnull([MYDBNAME].[dbo].[INV_InvestorFundLinking].[StockID] as [LNK].[StockID],[MYDBNAME].[dbo].[AE_RevenueData].[StockID] as [AE].[StockID]) AND [MYDBNAME].[dbo].[STG_LockedEntityData].[CapitalID] as [STG].[CapitalID]=[Expr1019])) 
     | |--Compute Scalar(DEFINE:([Expr1019]=isnull([MYDBNAME].[dbo].[INV_InvestorFundLinking].[CapitalID] as [LNK].[CapitalID],(0)), [Expr1026]=isnull([MYDBNAME].[dbo].[INV_InvestorFundLinking].[StockID] as [LNK].[StockID],(0)))) 
     |   |--Nested Loops(Left Outer Join, OUTER REFERENCES:([AE].[LinkID])) 
     |    |--Nested Loops(Inner Join, WHERE:([MYDBNAME].[dbo].[AE_RevenueData].[LinkID] as [AE].[LinkID]=[MYDBNAME].[dbo].[STG_LockedEntityData].[LinkID] as [STG].[LinkID])) 
     |    | |--Sort(ORDER BY:([Expr1027] ASC)) 
     |    | | |--Hash Match(Inner Join, HASH:([TE].[EntityID])=([AE].[EntityID])) 
     |    | |   |--Nested Loops(Inner Join, OUTER REFERENCES:([Uniq1008], [DE].[ListingID])) 
     |    | |   | |--Nested Loops(Inner Join, OUTER REFERENCES:([TE].[EntityID])) 
     |    | |   | | |--Table Scan(OBJECT:([MYDBNAME].[dbo].[DataEntityIDs] AS [TE])) 
     |    | |   | | |--Index Seek(OBJECT:([MYDBNAME].[dbo].[DE_DataEntities].[PK_DE_DataSources] AS [DE]), SEEK:([DE].[EntityID]=[MYDBNAME].[dbo].[DataEntityIDs].[EntityID] as [TE].[EntityID]) ORDERED FORWARD) 
     |    | |   | |--Clustered Index Seek(OBJECT:([MYDBNAME].[dbo].[DE_DataEntities].[IX_DE_DataSources] AS [DE]), SEEK:([DE].[ListingID]=[MYDBNAME].[dbo].[DE_DataEntities].[ListingID] as [DE].[ListingID] AND [Uniq1008]=[Uniq1008]) LOOKUP ORDERED FORWARD) 
     |    | |   |--Compute Scalar(DEFINE:([Expr1018]=[MYDBNAME].[dbo].[AE_RevenueData].[LinkID] as [AE].[LinkID], [Expr1020]=isnull([MYDBNAME].[dbo].[AE_RevenueData].[Formula] as [AE].[Formula],''), [Expr1021]=CONVERT(bit,[MYDBNAME].[dbo].[AE_RevenueData].[IsSumOfFunds] as [AE].[IsSumOfFunds],0), [Expr1022]=isnull([MYDBNAME].[dbo].[AE_RevenueData].[ClientSpecificSource] as [AE].[ClientSpecificSource],N''), [Expr1023]=isnull([MYDBNAME].[dbo].[AE_RevenueData].[GenericSource] as [AE].[GenericSource],N''), [Expr1027]=isnull([MYDBNAME].[dbo].[AE_RevenueData].[PSourceID] as [AE].[PSourceID],(0)))) 
     |    | |    |--Clustered Index Seek(OBJECT:([MYDBNAME].[dbo].[AE_RevenueData].[IX_AE_RevenueData] AS [AE]), SEEK:([AE].[ProjectID]=(13)), WHERE:([MYDBNAME].[dbo].[AE_RevenueData].[LinkID] as [AE].[LinkID] IS NOT NULL) ORDERED FORWARD) 
     |    | |--Table Scan(OBJECT:([MYDBNAME].[dbo].[STG_LockedEntityData] AS [STG])) 
     |    |--Index Seek(OBJECT:([MYDBNAME].[dbo].[INV_InvestorFundLinking].[PK_Linking_1] AS [LNK]), SEEK:([LNK].[LinkID]=[MYDBNAME].[dbo].[AE_RevenueData].[LinkID] as [AE].[LinkID]) ORDERED FORWARD) 
     |--Clustered Index Seek(OBJECT:([MYDBNAME].[dbo].[LKP_PrivateSource].[PK_LKP_FactsetSource] AS [PS]), SEEK:([PS].[PSourceID]=[Expr1027]) ORDERED FORWARD) 

Пожалуйста, смотрите ниже плана без Join на LKP_PrivateSource

|--Compute Scalar(DEFINE:([Expr1015]=CASE WHEN [Expr1024]=(0) THEN [MYDBNAME].[dbo].[AE_RevenueData].[StockID] as [AE].[StockID] ELSE [MYDBNAME].[dbo].[Linking].[StockID] as [LNK].[StockID] END)) 
    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Expr1027])) 
     |--Filter(WHERE:([MYDBNAME].[dbo].[STG_LockedEntityData].[StockID] as [STG].[StockID]=isnull([MYDBNAME].[dbo].[Linking].[StockID] as [LNK].[StockID],[MYDBNAME].[dbo].[AE_RevenueData].[StockID] as [AE].[StockID]) AND [MYDBNAME].[dbo].[STG_LockedEntityData].[CapitalID] as [STG].[CapitalID]=[Expr1017])) 
      |--Compute Scalar(DEFINE:([Expr1017]=isnull([MYDBNAME].[dbo].[Linking].[CapitalID] as [LNK].[CapitalID],(0)), [Expr1024]=isnull([MYDBNAME].[dbo].[Linking].[StockID] as [LNK].[StockID],(0)))) 
       |--Nested Loops(Left Outer Join, OUTER REFERENCES:([AE].[LinkID])) 
         |--Hash Match(Inner Join, HASH:([AE].[LinkID])=([STG].[LinkID])) 
         | |--Hash Match(Inner Join, HASH:([TE].[EntityID])=([AE].[EntityID])) 
         | | |--Nested Loops(Inner Join, OUTER REFERENCES:([Uniq1008], [DE].[ListingID])) 
         | | | |--Nested Loops(Inner Join, OUTER REFERENCES:([TE].[EntityID])) 
         | | | | |--Table Scan(OBJECT:([MYDBNAME].[dbo].[DataEntityIDs] AS [TE])) 
         | | | | |--Index Seek(OBJECT:([MYDBNAME].[dbo].[DE_DataEntities].[PK_DE_DataSources] AS [DE]), SEEK:([DE].[EntityID]=[MYDBNAME].[dbo].[DataEntityIDs].[EntityID] as [TE].[EntityID]) ORDERED FORWARD) 
         | | | |--Clustered Index Seek(OBJECT:([MYDBNAME].[dbo].[DE_DataEntities].[IX_DE_DataSources] AS [DE]), SEEK:([DE].[ListingID]=[MYDBNAME].[dbo].[DE_DataEntities].[ListingID] as [DE].[ListingID] AND [Uniq1008]=[Uniq1008]) LOOKUP ORDERED FORWARD) 
         | | |--Compute Scalar(DEFINE:([Expr1016]=[MYDBNAME].[dbo].[AE_RevenueData].[LinkID] as [AE].[LinkID], [Expr1018]=isnull([MYDBNAME].[dbo].[AE_RevenueData].[Formula] as [AE].[Formula],''), [Expr1019]=CONVERT(bit,[MYDBNAME].[dbo].[AE_RevenueData].[IsSumOfFunds] as [AE].[IsSumOfFunds],0), [Expr1020]=isnull([MYDBNAME].[dbo].[AE_RevenueData].[ClientSpecificSource] as [AE].[ClientSpecificSource],N''), [Expr1021]=isnull([MYDBNAME].[dbo].[AE_RevenueData].[GenericSource] as [AE].[GenericSource],N''))) 
         | |   |--Clustered Index Seek(OBJECT:([MYDBNAME].[dbo].[AE_RevenueData].[IX_AE_RevenueData] AS [AE]), SEEK:([AE].[ProjectID]=(13)), WHERE:([MYDBNAME].[dbo].[AE_RevenueData].[LinkID] as [AE].[LinkID] IS NOT NULL) ORDERED FORWARD) 
         | |--Table Scan(OBJECT:([MYDBNAME].[dbo].[STG_LockedEntityData] AS [STG])) 
         |--Index Seek(OBJECT:([MYDBNAME].[dbo].[Linking].[PK_Linking_1] AS [LNK]), SEEK:([LNK].[LinkID]=[MYDBNAME].[dbo].[AE_RevenueData].[LinkID] as [AE].[LinkID]) ORDERED FORWARD) 
+0

сделать план запроса без присоединиться и посмотреть, что происходит. –

+0

Вы также должны опубликовать план выполнения при удалении последнего 'LEFT JOIN'. Кроме того, это, вероятно, будет лучше подходит для http://dba.stackexchange.com – Lamak

+1

Несколько вещей, которые вы должны проверить, если вы еще этого не сделали: (a) устаревшая статистика, (b) статистика размер выборки слишком мал, (c) фрагментация индекса. –

ответ

2

По какой-то причине, добавляя LEFT JOIN к LKP_PrivateSource делает оптимизатор использовать NESTED LOOPS а вместо HASH JOIN, чтобы присоединиться к STG_LockedEntityData (что происходит раньше).

Трудно сказать, почему это так, но для улучшения вложенных циклов, создать индекс STG_LockedEntityData (stock_id, capital_id)

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