我在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
感谢任何帮助,请注意,连接发生在同一服务器上不同数据库的同一个表上。
答案 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)
返回什么,是内联表值还是多语句?
如果它是多语句那么
答案 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)