代码之家  ›  专栏  ›  技术社区  ›  Dustin Laine

SQL Server多个联接正在使CPU负担过重

  •  1
  • Dustin Laine  · 技术社区  · 15 年前

    我在SQLServer2005上有一个存储过程,它是从表函数中提取的,有两个连接。当使用负载测试运行查询时,它将100%杀死所有16个内核的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 回复  |  直到 15 年前
        1
  •  2
  •   Zack Angelo    15 年前

    这也许能说明这个问题。你能把第一个接头分成一个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
    )

    从FirstJoin fj中选择Skey 左联接[STAGING].dbo.RefSrvc c on fj.EID=c.esid

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

        2
  •  1
  •   Community CDub    7 年前

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

    如果是多重陈述的话

    • 对擎天柱来说是个黑匣子
    • 基数就是其中之一
    • 世界发展基金的结果没有统计数字

    answer here for why udfs can be bad

        3
  •  0
  •   HLGEM    15 年前

    您是否尝试过使用UNION all来代替它(我认为您试图得到的是那些具有当前查询无法识别的一个或另一个id的记录;t give,所有ti wouldl 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  
    

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

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

        4
  •  0
  •   egrunin    15 年前

    这将是一个更清晰的小样本输出,但我会跳进去。这对你有什么好处?

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