我试图修改包含在SP(TSQL)中的选择查询,以加快此SP。此查询的原始运行时间为几分钟,并将此查询分为两部分,仅将运行时间提高到几秒。未对已定义的索引进行任何更改,并且此查询仍使用相同的索引。有人可以解释究竟是什么导致了这一重大改进,为什么?
谢谢。
原始查询:
SELECT ( AgentFirstName + ' ' + AgentLastName ) AS AgentName,
AC.Agent_ID,
AC.TimeStamp
INTO #tAgentList
FROM AgentConfiguration AC
JOIN Getpermittedagents(@tenantId, @userName) AS PA
ON AC.Agent_ID = PA.Agent_ID
OR PA.Agent_ID = -1
WHERE AC.TimeStamp < @To
AND AC.Tenant_ID = @tenantId
AND ( EXISTS (SELECT *
FROM AgentsCampaignActivities AS ACA
WHERE AC.AgentGlobal_ID = ACA.AgentGlobal_ID)
OR @IsCampaignReport = 0 )
改进的查询:
SELECT Agent_ID,
AgentFirstName,
AgentLastName,
TimeStamp
INTO #tt
FROM AgentConfiguration
WHERE TimeStamp > @From
AND TimeStamp < @To
AND Tenant_ID = @tenantId
AND ( EXISTS (SELECT *
FROM AgentsCampaignActivities AS ACA
WHERE AgentGlobal_ID = ACA.AgentGlobal_ID)
OR @IsCampaignReport = 0 )
SELECT ( AgentFirstName + ' ' + AgentLastName ) AS AgentName,
tt.Agent_ID,
tt.TimeStamp
INTO #tAgentList
FROM Getpermittedagents(@tenantId, @userName) AS PA
JOIN #tt tt
ON tt.Agent_ID = PA.Agent_ID
OR PA.Agent_ID = -1
答案 0 :(得分:1)
这只是一个假设,可以通过比较执行计划来确认,但关键区别可能在这个子句中: ON AC.Agent_ID = PA.Agent_ID 或PA.Agent_ID = -1
这可能会在PA.Agent_ID使用索引时失败。
在第一种情况下,它在所有数据上执行,在第二种情况下在预过滤集上执行。
答案 1 :(得分:1)
在我看来,所提出的两个查询并不相同。在第二个你正在过滤TimeStamp&gt; @From,因为第一个查询不执行此操作。因此我猜测第一个查询处理的行数多于第二个查询。
答案 2 :(得分:0)
AgentConfiguration
和Getpermittedagents
之间的联接显然很昂贵。我的猜测是AgentConfiguration
需要Agent_ID
上的索引,但如果没有执行计划则很难判断。我建议你研究两个查询的执行计划。
答案 3 :(得分:0)
试试这个.. 在EXISTS部分中仅使用必需或索引的自动增量列名称。它减少了表中的READ数据。 “EXISTS(SELECT *”
请发布两个执行计划以获取更多信息。