為什麼Sql Server的查詢有時候第一次執行很慢,第二次,第三次執行就變快了

來源:互聯網
上載者:User

標籤:get   ase   proc   lease   script   gen   http   為什麼   target   

老外提問:

Hi, I have an sql query which takes 8 seconds in the first run. The next run there after takes 0.5 seconds and all consecutive runs take 0.5 seconds. Is the plan getting cached? How do i make this query run in 0.5 second in the first run itself? Please find the query below.

select isnull(joblabor.IDNumber,-1) ‘ProcessTransactionID‘,EmpNo ‘EmployeeID‘,case(joblabor.lJob) when ‘-1‘ then ‘0‘ else joblabor.ljob end ‘JobID‘,joblabor.ProcNo ‘ActivityID‘,process.Process ‘ActvityName‘, joblabor.shift ‘Shift‘,case (isnull(suspend,0)) when 1 then ‘true‘ else ‘false‘ end ‘Suspended‘,joblabor.StartTime ‘StartDateTime‘,joblabor.starttime ‘StartTime‘, joblabor.updated ‘UpdatedDate‘,ProcQuant ‘Quantity‘,Prochours ‘Hours‘,isnull(Remarks,‘‘) ‘Remark‘,IsNull(JCNotes,‘‘) ‘Notes‘,IsNULL(JobFormSpecs.PartDes,‘‘) as FormDesc,IsNull(Job.EstDes1,‘‘) ‘JobDesc‘,0 ‘Standard‘,0 ‘MinimumStd‘,0 ‘MaximumStd‘,JobLabor.PartNo ‘FormID‘,joblabor.CostDate ‘CostDate‘,isnull(JobLabor.linenum,1) ‘ProcessTransactionIndex‘,case(joblabor.suspend) when 1 then 1 else 0 end ‘ProcessType‘,(joblabor.timepct*100) ‘Percent‘,IsNull(Job.FCustNo,‘‘) ‘CustomerID‘, IsNull(Job.FCompany,‘‘) ‘CustomerName‘ , joblabor.EndTime ‘EndDateTime‘,process.ProcGroup ‘ActivityGroup‘,case (LEN(LTRIM(SUBSTRING(Job.remark1, 1, 25)))) when 0 then ‘false‘ else ‘true‘ end ‘HasJobNotes‘ ,case (isnull(ProcessRemarks.ContainsProcessRemarks,0)) when 0 then ‘false‘ else ‘true‘ end ‘HasProcessRemarks‘ ,case (isnull(ChangeOrder.ContainsChangeOrders,0)) when 0 then ‘false‘ else ‘true‘ end ‘HasAlteration‘,isnull(joblabor.costcode,‘‘) ‘CostStatus‘,isnull(Complete,‘‘) ‘CompletionCode‘,GRYield ‘GrossYield‘,NetYield ‘NetYield‘from BBJobCST joblabor (nolock)Left Outer Join bbjthead Job (nolock) on (joblabor.lJob = Job.lJob)inner join SSProces as Process (nolock) on( process.ProcNo = joblabor.ProcNo AND process.archive = 0)left outer join bbPthead JobFormSpecs (nolock) on (ltrim(rtrim(joblabor.Ljob)) = ltrim(rtrim(JobFormSpecs.LJob)) and ltrim(rtrim(JobLabor.PartNo))=ltrim(rtrim(jobFormSpecs.PartNo)) )left outer join (SELECT Count(bbchghdr.ljob) ‘ContainsChangeOrders‘, bbchghdr.ljob FROM bbchghdr (nolock)inner join bbchglin (nolock) ON bbchghdr.ljob = bbchglin.ljob AND bbchghdr.changeno = bbchglin.changenoWHERE type = ‘P‘ AND descript NOT LIKE ‘‘ group by bbchghdr.ljob) ChangeOrder on ChangeOrder.ljob=joblabor.ljobleft join (SELECT Count(bbjobcst.ljob) ‘ContainsProcessRemarks‘, bbjobcst.ljobFROM bbjobcst (nolock) WHERE ( LEN(LTRIM(SUBSTRING(bbjobcst.jcnotes, 1, 25))) > 0 or LEN(LTRIM(remarks)) > 0)Group By bbjobcst.ljob) ProcessRemarks on ProcessRemarks.ljob=joblabor.ljobwhere joblabor.empno = ‘000002013‘ and(isnull(joblabor.endtime,‘‘) = ‘‘ or suspend=1 ) and (joblabor.ProcHours = 0 or suspend=1 )and joblabor.ljob <> 0order by joblabor.Costdate desc,joblabor.starttime desc,[linenum] asc

Thanks in advance.

 

回答:

It isn’t the query plan that is getting cached – it is the actual data and indexes which are being cached.  This is common behavior of any database. If you ran the query, then waited a while and ran again (keeping the session active), you would see the query take longer again, based on the cached data/indexes being flushed to make room for other data.

You can see if you can reduce the 0.5 seconds repeat time, and/or you can see if you can reduce the intermediate result sets (which are usually what get cached and speed up the queries the second..nth runs).

If the query is producing a large intermediate result set (perhaps a large join where most records are then discarded), you may be able to speed it up by changing parts of your query.  Also, sometimes just adding the right index can solve issues like this.

Look at the execution plan and see if there are any “table access full”, “index access full”, “cartesian”, or similar joins indicating inefficient join/indexing.

 

意思就是說Sql語句第一次查詢慢的原因不僅僅是因為執行計畫沒有被緩衝這麼簡單,有時候你會發現Sql語句重用了執行計畫,但是第一次查詢還是很慢。就如同上面回答一樣,最主要的原因是第一次查詢的時候,Sql Server會將查詢出的部分資料和索引從磁碟載入到記憶體作為緩衝,而第二次查詢的時候就直接從記憶體緩衝中拿出資料了,自然要比從磁碟上載入資料快很多,Sql Server會定期清除緩衝,所以一段Sql語句如果長期不執行後,就需要從磁碟從新載入資料。

 

原文連結

 

為什麼Sql Server的查詢有時候第一次執行很慢,第二次,第三次執行就變快了

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.