优化SQL存储过程查询以获得更好的性能

时间:2017-07-30 03:03:37

标签: sql sql-server performance optimization

有没有办法优化下面的查询,因为从表中检索大量记录花了很长时间(T_School_Class)和(T_School)我为Name创建了索引以及T_School的SchoolCode。此外,还创建了临时表。

        SELECT Distinct (S.SchoolCode) As Code, Name from T_STU_School AS S
        LEFT JOIN T_STU_School_Class AS SC ON S.SchoolCode = SC.SchoolCode
        WHERE S.SchoolCode  IN
        (SELECT SchoolCode FROM @MainLevelCodeTemp)
        AND [Status] = 'A' 
        AND Name LIKE @Keyword
        AND (@AcademicCode = '' OR SC.AcademicLevel IN (@AcademicCode))
        Order BY Name ASC;

2 个答案:

答案 0 :(得分:1)

sproc中的所有命令都是浪费,你只是强迫SQL多次扫描T_STU_School,所有逻辑应该只添加到where子句中:

SELECT Distinct (S.SchoolCode) As Code, Name from T_STU_School AS S
LEFT JOIN T_STU_School_Class AS SC ON S.SchoolCode = SC.SchoolCode
WHERE ((@MainLevelCode LIKE '%J%' AND S.MixLevelType IN ('T1','T2','T6'))
   OR  (@MainLevelCode LIKE '%S%' AND S.MixLevelType IN ('T1','T2','T5','T6'))
   OR  (@MainLevelCode LIKE '%P%' AND S.MixLevelType IN ('T1','T2','T6'))
   OR  (MainLevelCode IN (SELECT Item FROM [dbo].[SplitString](@MainLevelCode, ',')))
   OR  @MainLevelCode = '')
AND [Status] = 'A' 
AND (@Keyword = '' OR Name LIKE @Keyword)
AND (@AcademicCode = '' OR SC.AcademicLevel IN (@AcademicCode))
Order BY Name ASC;

..即使您在NameSchoolCode上创建了索引,仍然按照您的执行计划扫描两个表的原因是因为SchoolCode上没有可降低的条件结果设置为小于整个表,并且只要Name为空,或者以“%”开头。要防止全表扫描,您应该在以下位置创建索引:

T_STU_School (Status, Name)
T_STU_School_Class (MixLevelType, SchoolCode)
T_STU_School_Class (MainLevelCode, SchoolCode)

..如果你在where子句中有(y='' OR x=y)这样的东西,最好在底部添加OPTION (RECOMPILE)以避免最终的错误计划缓存噩梦。

..这一行也可能是一个错误:

AND (@AcademicCode = '' OR SC.AcademicLevel IN (@AcademicCode))

IN不会解析@AcademicCode所以此声明等同于SC.AcademicLevel=@AcademicCode

答案 1 :(得分:0)

您肯定需要T_STU_SCHOOL.SchoolCode上的索引。您的查询计划显示65%的查询时间来自连接产生的索引扫描。 <{1}}列上的索引应该将其转换为索引搜索,这将更快。

当前未使用SchoolCode索引,可能是因为您传入了以通配符开头的Name值。鉴于Name位于T_STU_School表(行数较少)上,您可以在那里进行表扫描,以便按照您希望的方式使用通配符。所以你应该能够删除Name索引。