提高查询效率

时间:2013-12-03 19:00:27

标签: sql performance

如何提高效率?目前我需要22秒才能运行:

SELECT Id, PNumber, ClassId, ClassType, CreateDate, EndDate 
FROM dbo.tbl
WHERE DATEDIFF(d, EndDate, GETDATE())< 0 OR EndDate IS NULL 
AND ClassType NOT IN ('A', 'B', 'C') 
AND ClassId IN
( SELECT MAX(ClassId) FROM dbo.tbl 
WHERE ClassId IN (SELECT ClassId FROM dbo.tbl2 WHERE PNumber= '132456789')
GROUP BY PNumber)

2 个答案:

答案 0 :(得分:0)

这个怎么样:

SELECT A.Id, A.PNumber, A.ClassId, A.ClassType, A.CreateDate, A.EndDate 
FROM dbo.tbl A,
(
    SELECT MAX(tbl1.ClassId) AS MaxClassId FROM dbo.tbl tbl1
    WHERE EXISTS (SELECT 1 FROM dbo.tbl2 tbl2 WHERE tbl2.ClassId = tbl1.ClassId AND tbl2.PNumber= '132456789')
    GROUP BY PNumber
) B
WHERE ( A.EndDate IS NULL OR DATEDIFF(d, A.EndDate, GETDATE())< 0 )
AND A.ClassType NOT IN ('A', 'B', 'C') 
AND A.ClassId = B.MaxClassId

运行它并告诉我你的结果。

答案 1 :(得分:0)

我将能够提供更好的查询,但需要澄清。

的查询部分
 AND ClassId IN ( SELECT MAX(ClassId) 
                          FROM dbo.tbl 
                          WHERE ClassId IN 
                             ( SELECT ClassId 
                                  FROM dbo.tbl2 
                                  WHERE PNumber= '132456789')
                           GROUP BY 
                              PNumber)

只返回一个“ClassID”记录。由于ClassID在两个表中都是相同的,因此您无需查看所有内容,并且可以将其简化为。

 AND ClassId IN ( SELECT MAX( ClassId )
                     FROM dbo.tbl2 
                     WHERE PNumber= '132456789' )

由于你的PNumber是一个单独的数字,不需要按它分组,它只会返回该ID的max()类。

所以问题是......你打算只获得一个ClassID并从中运行吗?

现在,我要重写它,所以这是第一个查询...获取您关注的一个CLASS ID,然后使用其他条件获得此类型的所有其他条目。

SELECT 
      T.Id, 
      T.PNumber, 
      T.ClassId, 
      T.ClassType, 
      T.CreateDate, 
      T.EndDate 
   FROM 
      ( SELECT MAX( T2.ClassId ) MaxClass
           FROM dbo.tbl2 T2
           WHERE T2.PNumber= '132456789' ) OneClass
         JOIN dbo.tbl T
            on OneClass.MaxClass = T.ClassID
          AND NOT T.ClassType IN ( 'A', 'B', 'C' )
          AND ( T.EndDate IS NULL OR DATEDIFF(T.d, T.EndDate, GETDATE()) < 0  )

另请注意,我应用了所有alias.field引用来清楚字段来自哪个表,特别是涉及任何连接时。