Senere i stored proc bliver begge disse opdateret og inserted i et utal af gange. Det underlige er at første update i denne temp tabel tager 5 sekunder på min database og 11 sekunder på en kundes. Alle efterfølgende updates/inserts i begge tabeller tager 0 ms. Hvorfor tager den første 5 sekunder og kan jeg gøre noget ved det?
update #AllotmentLines blah if @@rowcount = 0 insert #AllotmentLines blah
Jeg har prøvet at lave en select count (*) fra #allotmentlines først men så tager selecten bare 5 sekunder istedet.
Hvor er TEMPDB placeret i forhold til Windows pagefile?
En temporær tabel findes kun i ram - så hvis du har et problem med fri ram, kan det simpelthen være et spørgsmål om swap. Typisk vil du have problemer med fri ram hvis der på samme maskine kører en webserver eller exchange.
Hvis TEMPDB er placeret sammen med pagefile eller med log til øvrige databaser, så kan du også komme ud i en situation med diskcontention - dvs. at der er for mange I/O operationer til at disken kan følge med.
Vi snakker multicpu 4 gb ram servere der ikke laver andet end at være SQL server! Så jeg tror ikke det er et ram problem eller disk io... Har du nogen andre forslag fordi det er da for underligt :)
Parallel query kan i nogen tilfælde være problematisk - man kommer i situationer hvor en query ender med at blokere sig selv - al CPU kraft ryger på administration af parallismen....
For sjovs skyld - prøv lige at køre en DBCC CHECKDB() i TEMPDB.
En anden ting; Kontroller at der ikke er slået Auto-Shrink eller Auto-close til på nogen af de baser du benytter.
Hvis du besøger www.quest.com så har de et værktøj der hedder Spotlight for SQL Server. Demo udgaven er begrænset, men den kan give dig et hurtigt indtryk af hvad der sker på serveren...
Autoshrink bør være slået fra. SQL Server ender med at stå og shrinke databasen for kort tid efter at udvide den igen. Det er ekstremt bekostelige affærer hvor SQL Serveren faktisk ikke kan svare på forespørgsler imens.
Så hvis du har autoshrink på din TEMPDB, så kan det godt være det der generer.
Jeg ville sætte TEMPDB til fx 2 GB med mulighed for at vokse i 50 MB blokke, og en Log fil på fx 500 MB med samme vokseværk.
2 ideer; Prøv at køre en stats_date(tabelid,indeksid) når du har indsat første række
Prøv at lave temp tabellen og dens indeks + første insert via query analyzer med Show Execution Plan slået til. Så vil du kunne se hvad pokker den har gang i når du kører.
Temp tabellen burde være registeret i sysobjects i TEMPDB, ikke i din egen db. Navnet vil være en let forvansket udgave af det navn du har givet (bruges til at sikre unikt navn pr session).
Det lugter for mig af, at du har enten dynamisk sql liggende i din SP, eller har blandet DML og DDL udtryk så du starter med en ekstrem bunke rekompileringer af proceduren.
Det er sådan, at for hver gang du skifter mellem fx CREATE (DDL) og INSERT (DML) der bliver din SP rekompileret - og når statistikkerne i en tabel opdateres, så rekompileres din SP igen.
Du kan altså ikke undgå rekompileringer når du har temp tabeller i en SP, men du kan minske antallet ved at bytte rundt på hvor når de forskellige udtryk bruges.
Option KEEP_PLAN bruges også til at forhindre agressive statistik opdateringer (første opdat på en temp-tabel kommer nemlig efter 6 indsatte rækker).
Evt. prøv at køre en profiletrace med recompile events slået til mens du afvikler din SP - så vil du kunne se hvordan det ser ud.
I øvrigt, hvis du bruger parametre til at styre hvilken kode der afvikles i en SP, så får du også et kompileringsmæssigt overhead + tungere query plan oprettelse. En typisk struktur der virker tilforladlig men giver dette problem er en sådan
create procedure dbo.vismig(@flag int) as begin if @flag=1 begin select * from mytable order by 1 end else if @flag=2 begin select * from yourtable order by 1 end else if @flag=3 begin select * from mytable union all select * from yourtable end end go
I ovenstående vil Query Optimizeren altså kompilere hele querien, ikke kun den del som @flag egentlig gør nødvendig - og så vidt jeg ved vil den også generere query planer for hver select...
Det er korrekt at jeg har parametre der styrer hvad der sker i proceduren. Den er på over 900 linier og der sker en masse.
Jeg har sat debug text ind i den for at benchmarke og ALT tager stort set ingen tid, undtagen den første tilgang til den ene temp tabel. De efterfølgende måske 2000 opdateringer af temp tabeller og mange opdateringer af rigtige tabeller tager ingen tid. Kun første tilgang af temp tabel. 5-11 sekunder! Jeg synes stadig det virker skummelt og intet forklarer det. Ihvertfald ikke recompile. Jeg kan også være heldig at den tager .5 sekund hvilket er underligt selv om jeg ændrer på parametre.
hvis du vil scripte sp'en og de nødvendige tabeller, så kan du maile det til mig på trer.fjerndette@mail.dk - så vil jeg godt lige prøve at kigge på det.
Fik lige en ide. Prøv at ændre dine temp tabeller i proceduren til permanente.
Check så performance - hvis det fungerer bedre, så skal du blot tilføje spid'en (@@SPID) til dine data og til dine where/join-betingelser for at kunne få det unikt pr bruger.
Ok det ændrede ikke noget at jeg gik fra temp. tabel til statisk tabel. Samme delay sker. Dette må betyde at det har noget med recompile at gøre selv om det ikke giver mening for mig at det sker lige der. Jeg kan ikke umiddelbart ændre på strukturen, det vil kræve en total rewrite og det kan ikke lade sig gøre.
Jeg har prøvet tabel variabler efter jeg læste den artikkel. Hjalp heller ikke noget :(
problemet var at jeg brugte et view som åbenbart pga størrelse eller noget gav dette underlig delay. jeg skrev et nyt og mindre view istedet og nu tager det ingen tid
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.