需要优化计数查询

时间:2014-03-04 14:37:12

标签: sql-server tsql

我正在尝试优化由前同事编写的慢速运行查询。他没有使用存储过程并直接在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查询已经有一段时间了,所以我有点生气!

4 个答案:

答案 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);