Sql server 需要优化计数查询

Sql server 需要优化计数查询,sql-server,tsql,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 )

我正在尝试优化一个前同事编写的运行缓慢的查询。他没有使用存储过程,直接在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查询了,所以我有点生疏了

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
我认为这里的计数(*)将是相同的答案

没有@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
通过将条件拉入联接,查询优化器似乎可以更好地进行早期筛选。
尤其是(@aId,@nId)中的r.PId,您很可能希望尽早申请

根据索引和表大小,这可能会更快(删除r.PId)


组合这两个查询只需要将其更改为(无需通过sql运行此命令来解析)


不幸的是,这可能无法解决您的速度问题。“结果”表和“预编码”表中索引了哪些列作为基于您的查询的一般建议:

replace为null或=X乘以isnull(变量,X)=X。它可以更改您的执行计划并解决or问题 将不在(查询)中的值替换为不存在(查询,其中列=值)。当条件完成时,exist停止搜索您的值,而不是在查询结束时,它也可能加快搜索速度

但这是一般性的建议,它不应该解决一个大问题。 最后,有时需要避免执行计划的问题,但是您知道为什么在最后一个查询中有两个查询而没有子查询吗? 你在别的地方用另一张桌子吗

这是密码

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 )
对子查询使用“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);

您是否做过任何类型的查询计划分析?是不是因为索引不好,所以速度很慢?还不是,我首先将查询转换为SP,因为它是这样的,几乎所有查询都是上述SELECT查询的某种变体。我认为查询在NOT in/in条件下需要花费时间,因为结果很大。您是否尝试使用临时表而不是变量?是否尝试针对一个诱人的[@PMasterTable]进行连接在该实例中甚至没有创建?@Talspaugh27如果at PMasterTable不可用,那么为什么插入有效?在原始实例中,插入到@PMasterTable中,然后使用该表连接选定的值。最好不要填充临时表,而严格按照查询的值本身进行操作。您是对的,该表已声明,但未填充,很抱歉我的评论有误。@Talspaugh27您不知道。这可能是一个昂贵的查询,只返回几行,并且在其他地方也会使用。但我认为如果可能的话,最好避免创建临时表的成本。OP还说“使用了PMasterTable”,这似乎表明使用它是他们试图避免的事情之一?!?
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 )
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);