Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 为什么通过在SQL查询中执行所描述的修改可以显著提高性能?_Sql Server_Performance_Tsql - Fatal编程技术网

Sql server 为什么通过在SQL查询中执行所描述的修改可以显著提高性能?

Sql server 为什么通过在SQL查询中执行所描述的修改可以显著提高性能?,sql-server,performance,tsql,Sql Server,Performance,Tsql,我试图修改一个包含在SP TSQL中的select查询,以加速此SP。此查询的原始运行时间为几分钟,将此查询分为两部分,将运行时间缩短为几秒钟。未对定义的索引进行任何更改,此查询仍使用相同的索引。有人能解释一下到底是什么导致了这一重大改进以及为什么 多谢各位 原始查询: SELECT ( AgentFirstName + ' ' + AgentLastName ) AS AgentName, AC.Agent_ID, AC.TimeStamp INTO #tAge

我试图修改一个包含在SP TSQL中的select查询,以加速此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 
AgentConfiguration和GetPermittedAgent之间的连接显然很昂贵。我的猜测是AgentConfiguration需要一个关于代理ID的索引,但是如果没有执行计划,很难判断。我建议您研究这两个查询的执行计划。

试试这个。。 在EXISTS节中仅使用必需的或索引的自动增量列名。它减少了从表中读取的数据。 存在选择*


请发布两个执行计划以获取更多信息。

这只是一个假设,可以通过比较执行计划来确认,但关键区别可能在于本条款: 在AC.Agent\u ID=PA.Agent\u ID上 或PA.Agent_ID=-1

这可能会破坏在PA.Agent_ID上使用索引的功能


在第一种情况下,它在所有数据上执行,在第二种情况下在预过滤集上执行。

在我看来,所提供的两个查询是不等价的。在第二个查询中,您将从where筛选where TimeStamp>@,因为第一个查询不会这样做。因此,我猜第一个查询处理的行比第二个查询多。

如果您想得到一个明确的答案,而不仅仅是对可能原因的一般推测,请发布两个执行计划。您可以有效地将连接顺序从ac join pa切换到pa join ac。您可能会产生相同的效果,当您在第一个查询中执行此操作时,根据优化的不同,GetPermitedAgent的使用在第二个查询中可能会大大减少。自从Getpermittedagents@tenantId,@userName是静态的,您是否尝试将结果初始值放入另一个诱惑中并加入此诱惑?早在2000年,我相信知道EXISTSSELECT*。。。不需要访问任何列来确定结果-它只需要测试行的存在性。您比我更了解:其中AC.TimeStampFrom和TimeStamp