有没有办法优化下面的查询,因为从表中检索大量记录花了很长时间(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;
答案 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;
..即使您在Name
和SchoolCode
上创建了索引,仍然按照您的执行计划扫描两个表的原因是因为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索引。