我正在尝试优化由前同事编写的慢速运行查询。他没有使用存储过程并直接在ADO.NET中编写查询,查询速度太慢。
我正在尝试将查询转换为单个SP。这个特殊的SELECT
语句需要花费太多时间。使用@PMasterTable逻辑在最后一个条件下使用了太多次。
INSERT INTO @PMasterTable
SELECT R.PId
FROM PRecord R
WHERE R.PId IN( @aId , @nId )
SELECT @DeleteCount = COUNT( P.Id )
FROM Result P
WHERE(P.Approved IS NULL
OR P.Approved = 0)
AND P.ACTION = 'D'
AND P.Id NOT IN( SELECT Id FROM ARecords )
AND P.PId IN( SELECT PId FROM @PMasterTable );
我写SQL查询已经有一段时间了,所以我有点生气!
答案 0 :(得分:0)
SELECT @DeleteCount = COUNT( P.Id )
FROM Result P
join @PMasterTable
on @PMasterTable.PId = P.PId
and ( P.Approved IS NULL
OR P.Approved = 0)
AND P.ACTION = 'D'
left join ARecords
on ARecords.Id = P.Id
where ARecords.Id is null
我认为count(*)在这里是相同的答案
没有@PMasterTable
SELECT @DeleteCount = COUNT( P.Id )
FROM Result P
join PRecord R
on r.PId = P.PId
and ( P.Approved IS NULL
OR P.Approved = 0)
and P.ACTION = 'D'
and r.PId IN( @aId , @nId )
left join ARecords
on ARecords.Id = P.Id
where ARecords.Id is null
通过将条件拉入连接,查询优化器似乎可以更早地过滤 特别是那个和r.PId IN(@ aId,@ ndd)很可能你想早点应用。
根据索引和表大小,这可能会更快(删除r.PId)
and P.PId IN( @aId , @nId )
答案 1 :(得分:0)
组合2个查询只需要将其更改为(不通过sql运行它来解析它)
SELECT @DeleteCount = COUNT( P.Id )
FROM Result P
inner join PRecord R on R.PId = P.PId
and R.PId IN( @aId , @nId )
WHERE isnull(P.Approved, 0) = 0
AND P.ACTION = 'D'
AND P.Id NOT IN( SELECT Id FROM ARecords )
不幸的是,这可能无法解决您的速度问题。在“结果”表和“PRecord”表中索引哪些列
答案 2 :(得分:0)
作为基于您的查询的一般建议:
由isnull(变量,X)= X替换为null或= X.它可能会更改您的执行计划并解决或解决问题 将您的值替换为(查询)不存在(查询其中column = Value)。当条件完成时,存在停止搜索您的值,而不是在查询结束时它也可以加速。
但这是一般性的建议它不应该解决一个大问题。 最后,有时它需要提出执行计划的问题,但是你知道为什么你有2个查询而不是最后一个子查询吗? 你在其他地方使用另一张桌子吗?
这是代码
SELECT @DeleteCount = COUNT( P.Id )
FROM Result P
inner join PRecord R on r.pid = p.pid
WHERE isnull(P.Approved,0) = 0
AND P.ACTION = 'D'
AND not exists ( SELECT * FROM ARecords as a where a.ID = P.Id)
and R.PId IN( @aId , @nId )
答案 3 :(得分:0)
对子查询使用“IN”或“NOT IN”可能会导致性能问题。然后你真的不需要子查询中的数据,因为你只是检查这个值是否存在。
试试这个:
SELECT @DeleteCount = COUNT( P.Id )
FROM Result P
WHERE(P.Approved IS NULL
OR P.Approved = 0)
AND P.ACTION = 'D'
AND NOT EXISTS (
SELECT 1 FROM ARecords AR WHERE AR.ID= P.Id )
AND EXISTS (
SELECT 1 FROM @PMasterTable PM WHERE PM.PId = P.PId);