SQL Server多个联接正在为CPU征税

时间:2010-04-12 21:57:35

标签: sql-server sql-server-2005 performance tsql user-defined-functions

我在SQL Server 2005上有一个存储过程。它是从Table函数中提取的,并且有两个连接。当使用负载测试运行查询时,它会在所有16个内核中100%杀死CPU!我已经确定删除其中一个连接会使查询运行正常,但两者都会对CPU征税。

 Select 
  SKey
 From 
  dbo.tfnGetLatest(@ID) a 
  left join [STAGING].dbo.RefSrvc b on 
   a.LID = b.ESIID
  left join [STAGING].dbo.RefSrvc c on 
   a.EID = c.ESIID 

感谢任何帮助,请注意,连接发生在同一服务器上不同数据库的同一个表上。

4 个答案:

答案 0 :(得分:2)

这可能会对这个问题有所了解。你能将第一次加入分成CTE吗?

这样的事情:

with FirstJoin(SKey,EID) as (
   select a.Skey,a.EID from 
       dbo.tfnGetLatest(@ID) a 
       left join [STAGING].dbo.RefSrvc b on a.LID = b.ESIID
)

select Skey from FirstJoin fj left join [STAGING].dbo.RefSrvc c on fj.EID = c.ESIID

此外,由于两个连接都是左连接,它们如何缩小结果集?该查询不等同于select sKey from dbo.tfnGetLatest(@ID)吗?

答案 1 :(得分:1)

dbo.tfnGetLatest(@ID)返回什么,是内联表值还是多语句?

如果它是多语句那么

  • 这是优化者的黑匣子
  • 基数是一个
  • 没有关于udf
  • 结果的统计信息

请参阅我的answer here for why udfs can be bad

答案 2 :(得分:0)

那么执行计划的不同之处是什么?这甚至是使用索引吗?

你是否尝试过全部使用UNION(我准备你想要获得的是具有当前查询所不具备的一个或另一个id的记录; t,所有ti woudl give是所有的完整列表skey值,根本不需要加入。)

Select  
    SKey 
From  
    dbo.tfnGetLatest(@ID) a  
    left join [STAGING].dbo.RefSrvc b on  
        a.LID = b.ESIID 
union all
Select  
    SKey 
From  
    dbo.tfnGetLatest(@ID) d  
    left join [STAGING].dbo.RefSrvc c on  
        d.EID = c.ESIID  

如果它没有使用索引但仍然可能效率不高但它可能会返回更好的记录集。

或者考虑将tablevalued函数返回的值放入临时表中,然后可以对其进行索引,然后进行连接。

答案 3 :(得分:0)

如果有一点样本输出,这会更加清晰,但我会跳进去。这对你有什么影响?

SELECT SKey FROM dbo.tfnGetLatest(@ID)
WHERE LID IN
    (SELECT ESIID from [STAGING].dbo.RefSrvc)
AND EID IN
    (SELECT ESIID FROM [STAGING].dbo.RefSrvc)