2013-03-09 73 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