需要使SQL子查询更有效

时间:2015-09-09 17:30:58

标签: sql oracle

我有一张包含所有学生的表格。

我需要查看我的注册表并查找所有学生,看看他们目前的状态。

如果是reg = y,那么请将其包括在搜索中,但是学生可能会从y更改为n所以我需要将其作为最近使用start_date来确定最新的reg状态。

下一步是如果n,则不要传递它。但是,如果最新的注册表为y,则使用pupil搜索pupilnumber表格;如果该瞳孔编号在pupils表中,则添加到计数中。

Select Count(*) 
From Pupils Partition(Pupils_01) 
Where Pupilnumber in (Select t1.pupilnumber 
                      From registered t1
                      Where T1.Start_Date = (Select Max(T2.Start_Date)
                                             From registered T2
                                             Where T2.Pupilnumber = T1.Pupilnumber)
                        And T1.reg = 'N');

此查询有效,但由于pupils表中有多条记录,因此速度非常慢。

只是想知道是否有任何方法可以提高效率

2 个答案:

答案 0 :(得分:0)

您可以查看此查询的执行计划。它将向您展示高成本的操作。如果您在执行计划中看到表扫描,则应对其进行索引。你也可以试试"存在"而不是"在"。

答案 1 :(得分:0)

此查询可能对您更有效,并希望您在相应表格中每个“pupilnumber”至少有索引。

为了澄清我在做什么,第一个内部查询是注册表和学生之间的连接,它预先确定他们在学生表中存在...你可以随时重新添加“分区”参考如果这有帮助。从那以后,它抓住了学生和他们的最大日期,所以它没有为每个学生做一个相关的子查询...让所有学生和他们的最大日期先...

然后,将该结果再次加入注册表...由学生再次和最大日期相同,并将最终注册状态限定为是。这应该可以为您提供所需的计数。

select
      count(*) as RegisteredPupils
   from
      ( select 
              t2.pupilnumber,
              max( t2.Start_Date ) as MostRecentReg
           from
              registered t2
                 join Pupils p
                    on t2.pupilnumber = p.pupilnumber
           group by
              t2.pupilnumber ) as MaxPerPupil
         JOIN registered t1
            on MaxPerPupil.pupilNumber = t1.pupilNumber
           AND MaxPerPupil.MostRecentRec = t1.Start_Date
           AND t1.Reg = 'Y'

注意:如果您在注册表中有多条记录,例如在同一日期注册多个类的人,那么您可能会得到错误的计数。如果可能是这种情况,您可以从

更改
COUNT(*)

COUNT( DISTINCT T1.PupilNumber )