减少Sql查询执行时间

时间:2016-10-21 18:33:43

标签: sql-server

我正在解决SQL查询执行所花费的时间问题。我经历了彻底的搜索,以减少执行时间。我正在处理数百万条记录(显然!)。

我的查询是从其他4个表加入的考勤表内部的讲座数。问题是需要1-2分钟才能执行。并且该查询用于计数是动态的循环(< 10)。连接超时结束。所以它不会工作。

我的查询是:

CREATE procedure [dbo].[Sp_TotalLecture_DateWise]
    (@CollegeId int = null,
     @AcademicYrId int = null,
     @Degreeid int = null,
     @StreamId int = null,
     @Semester nvarchar(50) = null,
     @SectionId int = null,
     @Course_Code nvarchar(100) = null,
     @frmdate nvarchar(50) = null,
     @ToDate nvarchar(50) = null)
as 
begin
    begin try
        Select 
            Count(at.StAttnd_Id) as TotalLecture 
        into 
            #t 
        from 
            ERP_AttendanceDetail as at 
        inner join 
            ERP_StudentAcadmicDetail as sad on at.Academic_Id = sad.Academic_Id 
        inner join 
            ERP_SectionAssign as Sa on sad.Section_ID = sa.Section_ID  
        inner join 
            ERP_StdntDetail as sd On sad.Stdnt_Id = sd.Stdnt_Id 
        inner join 
            ERP_Course as cd on sad.Course_Id = cd.Course_Id 
        Where 
            at.College_Id = @CollegeId 
            and SAD.AcademicYr_Id = @AcademicYrId
            and sa.Degree_Id = @Degreeid 
            and sa.Stream_Id = @StreamId 
            and sad.Semester = @Semester 
            and sad.Section_ID = @SectionId
            and cd.Course_Code = @Course_Code
            and at.Attnd_Date between convert(date, @frmdate, 106) 
                                  and convert(date, @ToDate, 106)    // If i remove search through date criteria, it will work fine and gives answer in 2-3 seconds.
        group by 
            sd.Stdnt_RegNo, sd.Stdnt_Name, sad.Stdnt_Id

    select max(TotalLecture) as TotalLecture 
    from #t

    drop table #t
end try
begin catch
end catch
end

我已经做过的事情是:

  1. 使用过程,临时表(如您所见)

  2. 为聚集索引提到的所有这些表设置主键(像往常一样)

  3. 使用非聚集索引在主键字段上创建另一个索引

  4. 此代码中最有趣的部分是,如果我通过日期条件删除搜索,它会完美运行并在2-3秒内给出答案(但我无法删除)。

    如果没有合适的解决方案。请告诉我如何长时间保持连接,因为它在两者之间丢失并且没有数据显示。我从.cs页面为200,000000这个特定程序保持命令超时。

    感谢。

2 个答案:

答案 0 :(得分:0)

尝试下面的查询,希望这可行

Select sd.Stdnt_RegNo, sd.Stdnt_Name, sad.Stdnt_Id, at.StAttnd_Id Into #t 
from ERP_AttendanceDetail as at 
inner join ERP_StudentAcadmicDetail as sad  on  at.Acadmic_Id=sad.Acadmic_Id 
inner join ERP_SectionAssign as Sa on sad.Section_ID=sa.Section_ID 
inner join ERP_StdntDetail as sd On sad.Stdnt_Id=sd.Stdnt_Id 
inner join ERP_Course as cd on sad.Course_Id=cd.Course_Id 
Where at.College_Id=@CollegeId 
and SAD.AcadmicYr_Id=@AcademicYrId
and sa.Degree_Id=@Degreeid 
and  sa.Stream_Id=@StreamId 
and  sad.Semester=@Semester 
and sad.Section_ID=@SectionId
and cd.Course_Code=@Course_Code
and at.Attnd_Date between convert(date,@frmdate,106) and convert(date,@ToDate,106)


Select Count(StAttnd_Id) StAttnd_Id into #t1 from #t
Group by Stdnt_RegNo, Stdnt_Name, Stdnt_Id


Select MAX(StAttnd_Id) StAttnd_Id from #t1

答案 1 :(得分:0)

性能取决于所有表结构和数据量。没有看完美的解决方案是有点雾。

尝试另一种方法, 在#temp1,#temp2 ....#temp5 tables中填写每个表的2或3个必填字段。在连接中使用它们创建索引 在日期字段上创建索引并确保在填写#temp时转换日期转换(日期,@ frmdate,106) 然后编写连接查询。

请勿在过滤时使用convert(date,@ frmdate,106),因为您已将日期转换为#temp

过滤器就像....

 and (at.Attnd >=@frmdate and at.Attnd<=@ToDate)

之后将连接查询结果存储在#t

Select Count(StAttnd_Id) StAttnd_Id into #t1 from #t
Group by Stdnt_RegNo, Stdnt_Name, Stdnt_Id


Select MAX(StAttnd_Id) StAttnd_Id from #t1

还有一件事......如果可能的话,在开始循环之前尝试填充#temp1,#temp2 .....#Temp5