2013-03-09 37 views
0

我有一個存儲過程,它非常慢,我不知道我可以改進。 sql服務器表EntityValue只包含1'800行。優化時間關鍵t-sql語句

這裏是存儲過程:

CREATE PROCEDURE [dbo].[GetReportLabelValues](
    @UnitIds UniqueIdentifierTableType readonly, 
    @LabelIds UniqueIdentifierTableType readonly) 
AS 
BEGIN 
    SELECT LabelValue.EntityId AS [LabelId], LabelValue.UnitId AS [UnitId], LabelValue.Value AS [Value] 
    FROM EntityValue, LabelValue 
    WHERE 
     EntityValue.IsDeleted = 0 AND 
     EntityValue.UnitId = LabelValue.UnitId AND 
     EntityValue.EntityId = LabelValue.EntityId AND 
     EXISTS (SELECT 1 FROM @UnitIds WHERE EntityValue.UnitId = [@UnitIds].Id) AND 
     EXISTS (SELECT 1 FROM @LabelIds WHERE EntityValue.EntityId = [@LabelIds].Id) 

END; 

什麼是錯的這種說法?或者我需要設置一些額外的指標? 感謝您的幫助提前:) 最好 月桂

編輯:

這裏是excution計劃:

DECLARE @unitIds AS UniqueIdentifierTableType; 
INSERT INTO @unitIds ([Id]) VALUES ('63ABF15E-B8B0-4240-9B90-08F324D5179E') 1 1 0 NULL NULL 1 NULL 1 NULL NULL NULL 0.01000216 NULL NULL INSERT 0 NULL 
    |--Table Insert(OBJECT:(@unitIds), SET:([Id] = [Expr1004]), DEFINE:([Expr1004]={guid'63ABF15E-B8B0-4240-9B90-08F324D5179E'})) 1 2 1 Table Insert Insert OBJECT:(@unitIds), SET:([Id] = [Expr1004]), DEFINE:([Expr1004]={guid'63ABF15E-B8B0-4240-9B90-08F324D5179E'}) [Expr1004]={guid'63ABF15E-B8B0-4240-9B90-08F324D5179E'} 1 0.01 1E-06 9 0.01000216 NULL NULL PLAN_ROW 0 1 

DECLARE @labelIds AS UniqueIdentifierTableType; 
INSERT INTO @labelIds ([Id]) VALUES ('4E75B50C-E647-42E7-A87F-2D23D8B63D17') 2 3 0 NULL NULL 2 NULL 1 NULL NULL NULL 0.01000216 NULL NULL INSERT 0 NULL 
    |--Table Insert(OBJECT:(@labelIds), SET:([Id] = [Expr1004]), DEFINE:([Expr1004]={guid'4E75B50C-E647-42E7-A87F-2D23D8B63D17'})) 2 4 3 Table Insert Insert OBJECT:(@labelIds), SET:([Id] = [Expr1004]), DEFINE:([Expr1004]={guid'4E75B50C-E647-42E7-A87F-2D23D8B63D17'}) [Expr1004]={guid'4E75B50C-E647-42E7-A87F-2D23D8B63D17'} 1 0.01 1E-06 9 0.01000216 NULL NULL PLAN_ROW 0 1 

exec dbo.GetReportLabelValues @unitIds, @labelIds 3 5 0 NULL NULL 3 NULL NULL NULL NULL NULL NULL NULL NULL EXECUTE PROC 0 NULL 

CREATE PROCEDURE GetReportLabelValues(
    @UnitIds UniqueIdentifierTableType readonly, 
    @LabelIds UniqueIdentifierTableType readonly) 
AS 
BEGIN 
    SELECT LabelValue.EntityId AS [LabelId], LabelValue.UnitId AS [UnitId], LabelValue.Value AS [Value] 
    FROM EntityValue, LabelValue 
    WHERE 
     EntityValue.IsDeleted = 0 AND 
     EntityValue.UnitId = LabelValue.UnitId AND 
     EntityValue.EntityId = LabelValue.EntityId AND 
     EXISTS (SELECT 1 FROM @UnitIds WHERE EntityValue.UnitId = [@UnitIds].Id) AND 
     EXISTS (SELECT 1 FROM @LabelIds WHERE EntityValue.EntityId = [@LabelIds].Id) 4 6 5 NULL NULL 5 NULL 1.062501 NULL NULL NULL 0.02785614 NULL NULL SELECT 0 NULL 
     |--Stream Aggregate(GROUP BY:([ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId]) DEFINE:([ABB_MDB2_Test].[dbo].[LabelValue].[Value]=ANY([ABB_MDB2_Test].[dbo].[LabelValue].[Value]))) 4 8 6 Stream Aggregate Aggregate GROUP BY:([ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId]) [ABB_MDB2_Test].[dbo].[LabelValue].[Value]=ANY([ABB_MDB2_Test].[dbo].[LabelValue].[Value]) 1.062501 0 1.062501E-06 343 0.02785614 [ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[Value] NULL PLAN_ROW 0 1 
      |--Nested Loops(Inner Join, OUTER REFERENCES:([ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [Id])) 4 9 8 Nested Loops Inner Join OUTER REFERENCES:([ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [Id]) NULL 1.062501 0 4.441255E-06 375 0.02785508 [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[Value] NULL PLAN_ROW 0 1 
       |--Nested Loops(Inner Join, WHERE:([ABB_MDB2_Test].[dbo].[EntityValue].[EntityId]=[Id])) 4 10 9 Nested Loops Inner Join WHERE:([ABB_MDB2_Test].[dbo].[EntityValue].[EntityId]=[Id]) NULL 1.062501 0 0.0001594845 55 0.02455766 [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId], [Id] NULL PLAN_ROW 0 1 
       | |--Nested Loops(Inner Join, OUTER REFERENCES:([Id])) 4 12 10 Nested Loops Inner Join OUTER REFERENCES:([Id]) NULL 38.15419 0 0.0001594845 39 0.01814615 [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId] NULL PLAN_ROW 0 1 
       | | |--Sort(DISTINCT ORDER BY:([Id] ASC)) 4 13 12 Sort Distinct Sort DISTINCT ORDER BY:([Id] ASC) NULL 1 0.01126126 0.000100023 23 0.01464438 [Id] NULL PLAN_ROW 0 1 
       | | | |--Table Scan(OBJECT:(@UnitIds)) 4 14 13 Table Scan Table Scan OBJECT:(@UnitIds) [Id] 1 0.003125 0.0001581 23 0.0032831 [Id] NULL PLAN_ROW 0 1 
       | | |--Clustered Index Seek(OBJECT:([ABB_MDB2_Test].[dbo].[EntityValue].[PK_EntityValue]), SEEK:([ABB_MDB2_Test].[dbo].[EntityValue].[UnitId]=[Id]), WHERE:([ABB_MDB2_Test].[dbo].[EntityValue].[IsDeleted]=(0)) ORDERED FORWARD) 4 15 12 Clustered Index Seek Clustered Index Seek OBJECT:([ABB_MDB2_Test].[dbo].[EntityValue].[PK_EntityValue]), SEEK:([ABB_MDB2_Test].[dbo].[EntityValue].[UnitId]=[Id]), WHERE:([ABB_MDB2_Test].[dbo].[EntityValue].[IsDeleted]=(0)) ORDERED FORWARD [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId], [ABB_MDB2_Test].[dbo].[EntityValue].[IsDeleted] 38.15419 0.003125 0.0001989696 40 0.00332397 [ABB_MDB2_Test].[dbo].[EntityValue].[UnitId], [ABB_MDB2_Test].[dbo].[EntityValue].[EntityId], [ABB_MDB2_Test].[dbo].[EntityValue].[IsDeleted] NULL PLAN_ROW 0 1 
       | |--Table Scan(OBJECT:(@LabelIds)) 4 17 10 Table Scan Table Scan OBJECT:(@LabelIds) [Id] 1 0.0032035 7.96E-05 31 0.006240574 [Id] NULL PLAN_ROW 0 38.15419 
       |--Clustered Index Seek(OBJECT:([ABB_MDB2_Test].[dbo].[LabelValue].[PK_LabelValue]), SEEK:([ABB_MDB2_Test].[dbo].[LabelValue].[UnitId]=[ABB_MDB2_Test].[dbo].[EntityValue].[UnitId] AND [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId]=[Id]) ORDERED FORWARD) 4 19 9 Clustered Index Seek Clustered Index Seek OBJECT:([ABB_MDB2_Test].[dbo].[LabelValue].[PK_LabelValue]), SEEK:([ABB_MDB2_Test].[dbo].[LabelValue].[UnitId]=[ABB_MDB2_Test].[dbo].[EntityValue].[UnitId] AND [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId]=[Id]) ORDERED FORWARD [ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[Value] 1 0.003125 0.0001581 343 0.003292982 [ABB_MDB2_Test].[dbo].[LabelValue].[UnitId], [ABB_MDB2_Test].[dbo].[LabelValue].[EntityId], [ABB_MDB2_Test].[dbo].[LabelValue].[Value] NULL PLAN_ROW 0 1.062501 
+2

而不是兩個相關的子查詢,你可以做一個連接。這是一個開始。至於「額外指數」 - 目前的指數是多少?他們正在使用?查詢計劃是什麼樣的? – Oded 2013-03-09 14:37:23

+0

你的執行計劃是什麼樣的? – Joe 2013-03-09 14:39:13

+0

這是什麼'UniqueIdentifierTableType'? – Kaf 2013-03-09 14:45:09

回答

2

試試這個,我轉換的子查詢到連接。

CREATE PROCEDURE [dbo].[GetReportLabelValues] 
(
    @UnitIds UniqueIdentifierTableType readonly, 
    @LabelIds UniqueIdentifierTableType readonly 
) 
AS 
BEGIN 
    SELECT LabelValue.EntityId AS [LabelId], 
      LabelValue.UnitId AS [UnitId], 
      LabelValue.Value AS [Value] 
    FROM EntityValue 
    JOIN LabelValue ON EntityValue.UnitId = LabelValue.UnitId AND 
        EntityValue.EntityId = LabelValue.EntityId 
    JOIN @UnitID ON EntityValue.UnitId = [@UnitIds].Id 
    JOIN @LabelIds ON EntityValue.EntityId = [@LabelIds].Id 
    WHERE EntityValue.IsDeleted = 0 
END; 
+0

完美,謝謝:) 順便說一句:改進是巨大的SQL分析器說從21'000 MS到940ms。 – LaurinSt 2013-03-11 09:00:40

+0

@LaurinSt - 正如所料,它從'O(X * 2Y)'到'O(X + 2Y)' – Hogan 2013-03-11 14:29:26