sql >> Database teknologi >  >> RDS >> Database

Opfølgning på markørindstillinger

Bemærk:Dette indlæg blev oprindeligt kun offentliggjort i vores e-bog, High Performance Techniques for SQL Server, bind 3. Du kan finde ud af om vores e-bøger her.

For over tre år siden skrev jeg et indlæg om markørindstillinger i SQL Server, og hvorfor du bør tilsidesætte standardindstillingerne:

  • Hvilken indflydelse kan forskellige markørindstillinger have?

Jeg ville sende en opfølgning for at gentage, at – selvom du aldrig bare skal acceptere standardindstillingerne – bør du virkelig tænke over, hvilke muligheder der er mest anvendelige for dit scenarie. Jeg ønskede også at præcisere et par punkter, der kom op i kommentarerne til det indlæg.

Andrew Kelly kom med en god pointe, og det er en STATIC markøren laver en engangskopi af resultaterne, sætter dem i tempdb og undgår derefter eventuelle samtidighedsproblemer, der kan påvirke en DYNAMIC cursoren. Den ene mulighed er ikke en klar vinder over den anden i alle tilfælde; for eksempel kan du have mange markører (eller markører med meget store resultatsæt) og/eller en allerede overbebyrdet tempdb og ønsker ikke at aflaste yderligere stress der. Men det er noget, der er værd at teste.

Fabiano kom også med et godt punkt, som både DYNAMIC og FAST_FORWARD markører kan være sårbar over for Halloween-problemet (diskuteret af Paul White i en 4-delt serie, der starter her). Paul kommenterede også, at FAST_FORWARD er muligvis ikke sårbar over for problemet, afhængigt af om optimeringsværktøjet valgte en statisk eller dynamisk plan (Microsofts Marc Friedman går i detaljer om det her).

Til sidst ville jeg påpege, at ikke alle standardmarkører er skabt lige. Jeg kørte nogle tests og tjekkede, hvordan SQL Server besluttede at indstille markørindstillinger under en række scenarier (valideret ved hjælp af sys.dm_exec_cursors dynamisk ledelsesfunktion). Koden er ret simpel:

DECLARE c CURSOR FOR [...blah blah...];
SELECT properties FROM sys.dm_exec_cursors(@@SPID);

Her er resultaterne for de scenarier, jeg testede:

Markørforespørgsel er baseret på... Typ Samtidig Omfang
en konstant (FOR SELECT 1 eller FOR SELECT SYSDATETIME() ) Snapshot Skrivebeskyttet Global
en #temp / ##temp tabel Dynamisk Optimistisk Global
en brugertabel / visning Dynamisk Optimistisk Global
en katalogvisning / DMV Snapshot Skrivebeskyttet Global
a join #tmp -> brugertabel / view Dynamisk Optimistisk Global
a join #tmp -> katalogvisning / DMV Snapshot Skrivebeskyttet Global
a join user table / view -> catalog view / DMV Snapshot Skrivebeskyttet Global

Kredit hvor der skal krediteres – denne undersøgelse blev udløst af et svar fra Jeroen Mostert på Stack Overflow.

Så du skal være opmærksom på, at standardindstillingerne for din markør, hvis du ikke tilsidesætter dem, kan være forskellige afhængigt af den forespørgsel, der ligger til grund for markøren. Hvis du forventer en specifik adfærd i nogen eller alle tilfælde, skal du vænne dig til eksplicit at angive de muligheder, du ønsker.

Men egentlig er pointen...

…hold op med at bruge markører. Der er virkelig meget få problemer i dag, hvor den bedste løsning er en markør, især hvis du er på SQL Server 2012 eller bedre – hvor stort set alle problemer, der traditionelt løses med markører, kan løses ved hjælp af forbedringer til vinduesfunktioner. Hvis du stadig føler, at du skal bruge markører, så tag venligst rådene i dette indlæg og dets forgænger for at bestemme, hvilke muligheder du skal bruge.


  1. Hvordan binder man parametre til en rå DB-forespørgsel i Laravel, der bruges på en model?

  2. Smart Home Data Model

  3. PostgreSQL-funktion, der returnerer flere resultatsæt

  4. Hvordan justify_hours() virker i PostgreSQL