sql >> Databasteknik >  >> RDS >> Database

Uppföljning av marköralternativ

Obs! Det här inlägget publicerades ursprungligen endast i vår e-bok, High Performance Techniques for SQL Server, Volym 3. Du kan ta reda på om våra e-böcker här.

För över tre år sedan skrev jag ett inlägg om marköralternativ i SQL Server, och varför du bör åsidosätta standardinställningarna:

  • Vilken effekt kan olika marköralternativ ha?

Jag ville lägga upp en uppföljning för att upprepa att – även om du aldrig bara ska acceptera standardinställningarna – bör du verkligen tänka på vilka alternativ som är mest tillämpliga på ditt scenario. Jag ville också förtydliga några saker som kom upp i kommentarerna till det inlägget.

Andrew Kelly tog upp en bra poäng, och det är en STATIC markören gör en engångskopia av resultaten, lägger dem i tempdb och undviker sedan eventuella samtidighetsproblem som kan påverka en DYNAMIC markören. Det ena alternativet är inte en klar vinnare över det andra i alla fall; till exempel kan du ha många markörer (eller markörer med mycket stora resultatuppsättningar) och/eller en redan överbelastad tempdb och vill inte avlasta någon ytterligare stress där. Men det är något som är värt att testa.

Fabiano tog också upp en bra poäng som både DYNAMIC och FAST_FORWARD markörer kan vara sårbar för Halloween-problemet (diskuterat av Paul White i en serie i fyra delar, som börjar här). Paul kommenterade också att FAST_FORWARD kanske inte är sårbar för problemet, beroende på om optimeraren valde en statisk eller dynamisk plan (Microsofts Marc Friedman går in i detalj om det här).

Slutligen ville jag påpeka att inte alla standardmarkörer skapas lika. Jag körde några tester och kollade hur SQL Server bestämde sig för att ställa in marköralternativ under en mängd olika scenarier (validerade med sys.dm_exec_cursors dynamisk förvaltningsfunktion). Koden är ganska enkel:

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

Här är resultaten för scenarierna jag testade:

Markörfrågan är baserad på... Typ Samtidighet Omfattning
en konstant (FOR SELECT 1 eller FOR SELECT SYSDATETIME() ) Ögonblicksbild Skrivskyddat Global
en #temp / ##temp tabell Dynamisk Optimistisk Global
en användartabell/vy Dynamisk Optimistisk Global
en katalogvy / DMV Ögonblicksbild Skrivskyddat Global
a join #tmp -> användartabell/vy Dynamisk Optimistisk Global
a join #tmp -> katalogvy / DMV Ögonblicksbild Skrivskyddat Global
en gå med användartabell / visa -> katalogvy / DMV Ögonblicksbild Skrivskyddat Global

Kredit där kredit ska betalas – den här utredningen utlöstes av ett svar från Jeroen Mostert på Stack Overflow.

Så du bör vara medveten om att standardalternativen för din markör, om du inte åsidosätter dem, kan vara olika beroende på frågan som ligger bakom markören. Om du förväntar dig ett specifikt beteende i något eller alla fall, ta för vana att uttryckligen ange de alternativ du vill ha.

Men egentligen är poängen...

…sluta använda markörer. Det finns verkligen väldigt få problem idag där den bästa lösningen är en markör, speciellt om du använder SQL Server 2012 eller bättre – där nästan alla problem som traditionellt löses med markörer kan lösas med hjälp av förbättringar av fönsterfunktioner. Om du fortfarande känner att du behöver använda markörer, vänligen ta råden i det här inlägget och dess föregångare för att avgöra vilka alternativ du ska använda.


  1. Ansluter till MySQL från Android med JDBC

  2. Paginering med OFFSET / FETCH :Ett bättre sätt

  3. FLOOR() Funktion i Oracle

  4. Det går inte att logga in på SQL Server + SQL Server Authentication + Fel:18456