我有一个查询,我已经调整了一段时间,但我似乎无法将执行时间缩短很多。在执行计划中,一切看起来都在做它应该做的事情,没有与查询的任何特定部分相关的大量成本,一切都在使用索引查找它应该在哪里。当我针对不同的客户端运行相同的查询时,它运行得相当快,但只返回150k记录。当我为我最大的客户端运行它时,它返回600k记录并花费超过十分钟。
我的问题可能是因为我正在返回的记录数量很难获得良好的性能,或者上面描述的内容是否在SQL Server的能力范围内?
答案 0 :(得分:6)
可能是行。但更有可能的是,生成4倍以上数据的客户端在其他区域的数据库上的活动量也增加了4倍。这意味着内存使用量增加4倍,磁盘数量增加4倍,锁定量增加4倍。确保硬件分配正确。
但继续前进,我试图想象一下,对于返回600K记录甚至150K记录的查询,您可以做些什么有用的工作。我假设这些从未向最终用户显示,因为即使是分页太多而且无用。如果没有,我们需要考虑如何使用这些数据。
如果这是一个批处理过程,也许10分钟就完全没问题了,没有理由花费你宝贵的时间进一步处理它。如果它与其他查询结合使用,可能需要尽快引入该查询中的元素,以保持结果集更小。
答案 1 :(得分:3)
除了记录数量之外,两个系统之间还有什么不同之处:
比较SET STATISTICS IO ON的两个位置时:
当然,这些是在黑暗中没有适当数据来支持它们的狂野镜头。认为他们是一个猜测,而不是一个权威的解决方案。
答案 2 :(得分:1)
您需要首先确定实际查询所花费的时间,然后您可以确定将整个600K行返回到客户端所花费的时间(您可能不应该这样做)。假设每行数据都是100字节,那么您将向客户端返回60MB。那将是痛苦的。
答案 3 :(得分:1)
我应该从多少返回的记录开始预期性能问题?
一个人。
此查询:
SELECT COUNT(*)
FROM myreallybigtable
将只返回一条记录,但您可能需要等待数小时才能完成。
客户端 - 服务器I/O
(可能是唯一依赖依赖返回记录的数量和大小的东西)通常是最不重要的因素之一。
真正重要的是查询计划,它指定了基础表中的记录访问,转换和返回的方式和顺序。
因此,正如其他人所建议的那样,只需在此处发布您的查询,我们就可以告诉您如何优化它。
答案 4 :(得分:1)
查看您的IO统计信息:
Table 'RefStuExitCatg'. Scan count 1, logical reads 22810 ...
Table 'RefEngLangArtsTestProfcy'. Scan count 1, logical reads 22810 ...
Table 'RefEngLangAcqstnStatSt'. Scan count 1, logical reads 22810 ...
VS
Table 'RefStuExitCatg'. Scan count 1, logical reads 1514532, ...
Table 'RefEngLangArtsTestProfcy'. Scan count 1, logical reads 1514532,...
Table 'RefEngLangAcqstnStatSt'. Scan count 1, logical reads 1514532, ...
快速查询必须在所有“Ref ...”表上阅读22810页。相比之下,慢查询必须读取1514532页。这是1.5M对22k, 66次更多。因此,您的慢速数据库的方式,方式,数据大小差异大于您知道的150k和600k行。我想说这是对差异的一个非常好的解释。
答案 5 :(得分:0)
您是否通过索引调整向导运行查询?即使您已经在使用索引,其他索引(尤其是复合索引)仍有可能提高性能。
将查询分解为具有临时表的部分也可能会改进。
我们在报告系统中运行查询,这些查询通常返回300,000条记录,连接20个表,其中包含许多共同相关的子查询,并获得亚秒响应时间。
答案 6 :(得分:0)
好吧支撑自己.... 这是我继承的原始存储过程。如果您想看到我所做的更改,请告诉我。
带有“--HERE”注释的部分是真正的性能问题开始的地方。
ALTER PROCEDURE [dbo].MyProc
@LEAESIID int,
@AcademicYear varchar(10),
@ReportType varchar(16),
@SchoolESIID varchar(max),
--
@Grade varchar(8000),
@Gender varchar(8000),
@Race varchar(8000),
--
@AsOfDate datetime,
--
@UserID int
AS
create table #TempSchool
(
SchoolESIID int
)
Create table #TempRace
(
Race varchar(60)
)
declare @CALPADSSnpshtKey int
select @CALPADSSnpshtKey =
CALPADSSnpshtKey
from vwCertSnpshtRptngSnpsht cs2
Where
-- Filter to correct snapshot
rtrim(ltrim(cs2.AcdmcYearCode)) = rtrim(ltrim(@AcademicYear)) AND
rtrim(ltrim(cs2.LEARptngEsiId)) in (select rtrim(ltrim(ParsedValue)) from dbo.tfnParseStringIntoTable(@LEAESIID, ',')) AND
rtrim(ltrim(cs2.RptngTypeCode)) = rtrim(ltrim(@ReportType))
Insert into #TempSchool
select ParsedValue from dbo.tfnParseStringIntoTable(@SchoolESIID, ',')
Insert into #TempRace
select ParsedValue from dbo.tfnParseStringIntoTable(@Race, ',')
/*
Select query to pull back data from the reporting views.
Since this report is based around enrollment information, the primary table will be StuEnrlmt.
*/
declare
@UserLevel nVarchar(10),
@ESILEAList nvarchar(max),
@ESISchoolList nvarchar(max)
-- added by jackson chan 090109
-- program
create table #tmpProgramSet (
StuKey int
, CALPADSSnpshtKey int
, TitleIPartCMigrantFlag char(1)
, SocioEconomicallyDisadvantagedFlag char(1)
, SpecialEducationFlag char(1)
, GiftedAndTalentedFlag char(1)
)
insert into #tmpProgramSet
select se.StuKey,
se.CALPADSSnpshtKey ,
max(isnull(case sp.EduPgmCode
when '135' then 'Y'
else 'N'
end, 'N')) as TitleIPartCMigrantFlag,
max(case
when
isnull(sp.EduPgmCode, 000) = 175 OR
isnull(s.HighstEduLvlCode, 0) = 14
then 'Y'
else 'N'
end ) as SocioEconomicallyDisadvantagedFlag,
max(isnull(case sp.EduPgmCode
when '144' then 'Y'
else 'N'
end, 'N')) as SpecialEducationFlag,
max(isnull(case sp.EduPgmCode
when '127' then 'Y'
else 'N'
end, 'N')) as GiftedAndTalentedFlag
from dbo.vwStuEnrlmtRptngSnpsht se inner join
dbo.vwStuRptngSnpsht s on
se.StuKey = s.StuKey and
se.CALPADSSnpshtKey = s.CALPADSSnpshtKey
inner join #TempSchool schl2 on
se.SchlAtndncEsiID = schl2.SchoolESIID and
se.LEARptngESIID = @LEAESIID left outer join
dbo.vwStuPgmRptngSnpsht sp on
se.StuKey = sp.StuKey and
se.CALPADSSnpshtKey = sp.CALPADSSnpshtKey
group by se.StuKey, se.CALPADSSnpshtKey
order by se.StuKey;
--HERE
Select distinct
se.LEARptngEsiID,
se.SchlAtndncEsiID as SchlAtndncEsiID,
se.SchlAtndncCDSCode as SchlAtndncCode,
se.SchlAtndncName as SchlAtndncName,
se.SchlAtndncType as SchlAtndncType,
se.StuKey,
s.StuIDStwdCal,
isnull(s.StuLastOrSrnmLgl,'') + ', ' + isnull(s.StuFstNameLgl,'') + ' ' + isnull(s.StuMdlNameLgl,'') as StudentName,
se.StuIDLcl,
s.GndrCode,
isnull(case
when s.StuHspncEnctyIndctr = 'Y' then 'Hispanic'
when s.StuEnctyMsngIndctr = 'Y' or s.StuRaceMsngIndctr = 'Y' then 'Missing'
when s.EthnicityRaceCode2 is not null then 'Multiple' -- if a second race is populated,then Multiple
else s.EthnicityRaceCode1
end, 'Missing') as RaceEnthnicity,
se.GrdLvlCode,
isnull(
case s.EngLangAcqstnStatStCode
when 'EL' then 'Y'
else 'N'
end, 'N') as EnglishLearner,
isnull(
case
when
-- if a value is null, set it to any value that will evaluate to false in the expression
-- only students with valid information should be counted as Title III Eligible Immigrants
-- disabled by jackson chan 12/08/09. Per defect 1605, Student Birth Country Special Circumstance Indicator is not a required field anymore
--isnull(s.StuIneligSnorImgrntIndctr, 'Y') = 'N' AND
isnull(s.StuEnrldUSSchlLessThanThreCumltvYrsIndctr, 'N') = 'Y' AND
isnull(s.CntryCode, 'US') != 'US' AND
isnull(se.EnrlmtStatCode, '0') = '10' AND
-- Calculate age from birth date
isnull(case
when datepart(month, s.StuBirDate) < datepart(month, getdate())
then datediff(year, s.StuBirDate, getdate())
when datepart(month, s.StuBirDate) = datepart(month, getdate()) and datepart(day, s.StuBirDate) <= datepart(day, getdate())
then datediff(year, s.StuBirDate, getdate())
else datediff(year, s.StuBirDate, getdate()) -1
end , 0) between 3 and 21 AND
isnull(se.GrdLvlCode, 'AD') != 'AD'
then 'Y'
else 'N'
end, 'N') as TitleIIIEligibleImmigrantFlag,
sp.SocioEconomicallyDisadvantagedFlag,
isnull(case when s.EngLangAcqstnStatStCode in ('EL', 'RFEP') AND s.EngLangArtsTestProfcyCode = 'N' then 'Y'
else 'N'
end, 'N') as LimitedEnglishProficientFlag,
sp.TitleIPartCMigrantFlag,
sp.SpecialEducationFlag,
sp.GiftedAndTalentedFlag
From
dbo.vwStuEnrlmtRptngSnpsht se
inner join dbo.vwStuRptngSnpsht s on
se.StuKey = s.StuKey and
se.CALPADSSnpshtKey = s.CALPADSSnpshtKey
left join #tmpProgramSet sp on
se.StuKey = sp.StuKey and
se.CALPADSSnpshtKey = sp.CALPADSSnpshtKey
inner join #TempSchool schl on
se.SchlAtndncEsiID = schl.SchoolESIID and
se.LEARptngESIID = @LEAESIID
inner join #TempRace r on
isnull(case
when s.StuHspncEnctyIndctr = 'Y' then 'Hispanic'
when s.StuEnctyMsngIndctr = 'Y' or s.StuRaceMsngIndctr = 'Y' then 'Missing'
when s.EthnicityRaceCode2 is not null then 'Multiple' -- if a second race is populated,then Multiple
else s.EthnicityRaceCode1
end, 'Missing') = r.Race
Where
-- Enrollments
se.StuEsiRltnspExpctdSchlStartDate <= @AsOfDate AND (se.WithdrlDate is null OR se.WithdrlDate >= @AsOfDate) AND
se.EnrlmtStatCode = '10' AND
se.StuExitCatgCode != 'N470' AND -- no shows are not considered in active enrollment numbers
-- Filter to correct snapshot
se.CALPADSSnpshtKey = @CALPADSSnpshtKey AND
-- User selection filters
rtrim(ltrim(se.GrdLvlCode)) in (select rtrim(ltrim(ParsedValue)) from dbo.tfnParseStringIntoTable(@Grade, ',')) AND
rtrim(ltrim(s.GndrCode)) in (select rtrim(ltrim(ParsedValue)) from dbo.tfnParseStringIntoTable(@Gender, ','))
答案 7 :(得分:0)
尝试在临时表上放置索引,看看是否有帮助。
答案 8 :(得分:0)
以下是在合理的时间内完成的查询的IO统计信息:
Table '#tmpProgramSet_0000000017E2'. Scan count 11405, logical reads 36450, physical reads 0, read-ahead reads 61, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefStuExitCatg'. Scan count 1, logical reads 22810, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefEngLangArtsTestProfcy'. Scan count 1, logical reads 22810, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefEngLangAcqstnStatSt'. Scan count 1, logical reads 22810, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#TempRace_0000000017E1'. Scan count 1, logical reads 11405, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#TempSchool_0000000017E0'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'stu'. Scan count 10939, logical reads 47465, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#68CACE20'. Scan count 1, logical reads 13814, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefEductlSrvcInstn'. Scan count 1, logical reads 448, physical reads 0, read-ahead reads 372, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefEnrlmtStat'. Scan count 1, logical reads 27628, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'StuEnrlmt'. Scan count 2, logical reads 141994, physical reads 60, read-ahead reads 200, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefGrdLvl'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#4D22B3AB'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefGndr'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefCntryCode'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefRace'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefFedEnctyRaceCatg'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
以及我长时间运行的查询
Table '#tmpProgramSet_0000000017F5'. Scan count 757266, logical reads 2418742, physical reads 0, read-ahead reads 158, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefStuExitCatg'. Scan count 1, logical reads 1514532, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefEngLangArtsTestProfcy'. Scan count 1, logical reads 1514532, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefEngLangAcqstnStatSt'. Scan count 1, logical reads 1514532, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#TempRace__0000000017F4'. Scan count 1, logical reads 757266, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#TempSchool__0000000017F3'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'stu'. Scan count 586229, logical reads 2711554, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#065B3107'. Scan count 1, logical reads 637919, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefEductlSrvcInstn'. Scan count 1, logical reads 448, physical reads 0, read-ahead reads 332, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefEnrlmtStat'. Scan count 1, logical reads 1276828, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'StuEnrlmt'. Scan count 2, logical reads 2692331, physical reads 1386, read-ahead reads 97737, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefGrdLvl'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#780D11B0'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefGndr'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefCntryCode'. Scan count 1, logical reads 4, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefRace'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'RefFedEnctyRaceCatg'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
答案 9 :(得分:0)
您是否考虑过两个站点的数据库物理设计? 有可能,具有大型DB的客户端将较旧的数据存储在较慢的磁盘上,并且 可能是慢慢运行查询的原因..