Performance Tuning

Uge 11: Recompilations

I denne uge tager jeg fat på endnu en del af området omkring Execution Plans – nemlig Recompilations.

En Recompilation sker på SQL serveren, når man eksekverer en query (SQL serveren er i gang med at trække data) og en anden aktivitet på serveren har gjort resten af Execution Planen ikke kan forløbe. I disse tilfælde vil SQL serveren stoppe og lave en fuld ny Execution Plan og dermed trække en del ekstra CPU kraft, som så bliver taget fra andre processer på SQL serveren.

Hvad er en Recompilation så?

Først skal jeg lige være helt klar i sproget her – der er forskel på en Recompilation og en Compilation. I uge 9 skrev jeg om compilations af Execution Plans på SQL serveren. En compilation sker altid på SQL serveren når Query Optimizeren oversætter en query til en fysisk Execution Plan. Dette er altså en compilation FØR query eksekveringen starter.

En Recompilation er en proces, der sker UNDER eksekveringen af en query. Derfor laver SQL serveren en delvis Recompile for at tilsikre at det rigtige data bliver behandlet. Et eksempel kan være at et index, som bliver anvendt i execution planen, er blevet slettet. Dette vil føre til forkerte resultater på det behandlede data og SQL serveren trigger derfor en Recompilation af den del af execution planen som indeholder dette index.

SQL serveren trigger en Recompilation baseret på to dele:

  • Correctness-based Recompilations
  • Optimality-based Recompilations

I den første del – Correctness-based Recompilations – sker når en execution plan ikke længere er korrekt. Et schema er måske ændret (nyt index, drop af statistics) eller når der er sket en ændring i en SET operation. Her bliver der triggeret en Recompilation for at tilsikre at execution planen forbliver korrekt.

Recompilations
Eksempel på visning af Recompilation fra SQL Trace

Den anden del – Optimality-based Recompilations – sker det fordi statistics (kommer der mere som senere) er blevet ændret. SQL serveren har selv opdateret statistics, eller en slutbruger har startet processen for at opdatere dem. I dette scenarie kunne det være at Bookmark Lookup nu er over Tipping Point og SQL serveren skal derfor bruge en ny execution plan for at anvende en fuld table scan eller et Clustered Index Scan.

Et lidt dybere dyk ned i scenarier der trigger Recompilations under en query og dennes eksekvering – Temp tables…

Temp Tables

Ja, når du arbejder med temp tabeller på SQL serveren så forcerer du en Recompilation. Et eksempel på en stored procedure:

create procedure DoWork as
begin
   create table #TempTable
   (
      id int identity(1, 1) primary key,
      Fornavn char(4000),
      Efternavn char(4000)
   )
   insert into #TempTable (Fornavn, Efternavn)
   select top 1000 name, name from master.dbo.syscolumns
 
   select * from #TempTable
end
go

Den ovenstående stored procedure opretter en temp tabel, insætter nogen rækker i den og slutteligt trækker alle rækker ud fra tabellel. En forholdsvis simpel øvelse – men den trigger to Recompilations:

  • Den første Recompliation sker på baggrund af den oprettede temp tabel. Ved at oprette en ny tabel (om den er temp eller ej) ændres database schema. Dette trigger en Correctness-based Recompilation
  • Den anden Recompilation sker på baggrund af det sidste select statement. Der er netop blevet indsat rækker i tabellen og statistics er dermed netop også blevet ajourført/opdateret. Dette trigger en Optimality-based Recompilation.

Men hvordan kommer man så uden om disse Recompilations? Man kan bruge Table variabler i stedet for (dem med ‘@’ foran). Med en tabel variabel ændrer man ikke ved database schema. Det er nemlig kun en variabel som ikke har statistics påhæftet. Dermed vil begge ovenstående Recompilations være fjernet. Det kan naturligvis introducere en række andre performance problemer med tabel variabler: Der er ikke nogen statistics og SQL serveren estimerer dermed ALTID kun 1 række, så Cardinality Estimation kan blive helt forskruet og forkert.

Af denne årsag er tabel variabler brugbare i specifikke scenarier på SQL serveren. Når der er små mængder af data. Hvis det er større datamængder, bør man stadig anvende en temp tabel da den så har de nødvendige statistics og man kan lave index på dem. Bagsiden her er de Recompilations som det giver.

Vil du læse mere om Recompilations, kan du se nogen gode links nedenfor:

Opsummering – Recompilations

Så i dette indlæg har jeg forsøgt at hjælpe dig godt i gang med at forstå Recompilations på SQL serveren og hvorfor de kan være farlige. Man kan ikke komme uden om dem, da de skal til for at SQL serveren kan arbejde korrekt med data.

En tilgang ved at være meget opmærksom på at vælge mellem # og @ tabeller (temp og variabler) kan gøre det store udslag i den oplevede performance.

Husk at skrive dig på maillisten nedenfor, så du ikke misser næste udgave af denne blogserie. Jeg lover dig kun at sende en mail, når der er nyt i denne serie.

Få besked om næste indlæg

Skriv dig gerne op til at modtage en mail, ved næste indlæg. Det kan du gøre nedenfor.



Marketing stuff

Our emails contain marketing stuff, so we need to give you some fine quality fine print: brianbonk will use the information you provide on this form to email you with updates and marketing. You can change your mind at any time by clicking the unsubscribe link in the footer of any email you receive from us, or by contacting us at help@brianbonk.dk. We use Mailchimp as our marketing platform. By checking the box to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing, and that we may process your information in accordance with these terms.

Følg mig på Instagram

Leave a Reply

Your email address will not be published. Required fields are marked *

en_USEnglish