Frågan är ett enda val som innehåller många grupperingsnivåer och aggragatoperationer. Med SET ARITHABORT ON tar det mindre än en sekund, annars tar det flera minuter. Vi har sett detta beteende på SQL Server 2000 och 2008.
Svar
Lite daterat, men för alla som hamnar här med ett liknande problem …
Jag hade samma problem. För mig visade det sig vara parametersniffning, som först förstod jag inte nog att bry mig om. Jag lade till en ”set arithabort on” som fixade problemet men sedan kom det tillbaka. Sedan läste jag:
http://www.sommarskog.se/query-plan-mysteries.html
Det rensades upp – allt eftersom jag använde Linq för att SQL och hade begränsade alternativ för att åtgärda problemet, jag slutade med att använda en frågeplanguide (se slutet av länken) för att tvinga den frågeplan jag ville ha.
Kommentarer
- Mer än sex år senare är länken i detta svar fortfarande ” krävs läsning ” … och fortfarande nuvarande, den senaste versionen är december ’ 17.
Svar
.NET-applikationer ansluts till alternativet inaktiverat som standard, men det är aktiverat som standard i Management Studio. Resultatet är att servern faktiskt cachar 2 separata exekveringsplaner för de flesta / alla procedurer. Detta påverkar hur servern utför numeriska beräkningar och som sådan kan du få väldigt olika resultat beroende på proceduren. Det här är egentligen bara ett av två vanliga sätt som en proc kan få matat på en fruktansvärd exekveringsplan, det andra är parameter sniffing.
Ta en titt på https://web.archive.org/web/20150315031719/http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Effects-Stored-Procedure-Performance.aspx för lite mer diskussion om det.
Kommentarer
Svar
Jag skulle argumentera för att detta nästan säkert var parameter sniffing.
Det anges ofta att SET OPTIONS
kan påverka prestanda på detta sätt men jag har ännu inte sett en enda auktoritativ källa för detta påstående förutom fallet där du är med indexerade vyer / bestående beräknade kolumner.
I det här fallet (för SQL2005 + och såvida inte din databas är i SQL2000-kompatibilitetsläge ). Om du har både ARITHABORT
och ANSI_WARNINGS
OFF
hittar du att indexet inte används så kan ha en genomsökning snarare än önskad sökning (och vissa omkostnader eftersom det bestående beräkningsresultatet inte kan användas). ADO.NET verkar som standard ha ANSI_WARNINGS ON
från ett snabbtest som jag just gjorde.
Påståendet i Bens svar att ”hur servern utför numeriska beräkningar” kan lägga till minuter till ett resultat som annars skulle ta mindre än en sekund bara inte verkar trovärdigt för mig. Jag tror att det som tenderar att hända är att Profiler används för att identifiera den stötande frågan när man undersöker ett prestandaproblem. Detta klistras in i ledningsstudion och körs och returnerar resultat direkt. Den enda uppenbara skillnaden mellan anslutningar är alternativet ARITH_ABORT
.
Ett snabbtest i ett fönster för managementstudio visar att när SET ARITHABORT OFF
är påslagen och frågan körs att prestandaproblemet återkommer så att det tydligen är fallet. Detta verkar faktiskt vara felsökningsmetoden som används i länken Gregg Stark .
Men det ignorerar det faktum att du med den här inställningen kan sluta få exakt samma dåliga plan från cacheminnet .
Denna planåteranvändning kan ske även om du är inloggad som en annan användare än applikationsanslutningen använder.
Jag testade detta genom att utföra en testfråga först från en webbapplikation och sedan från managementstudion med SET ARITHABORT OFF
och kunde se användarräkningarna gå upp från frågan nedan.
SELECT usecounts, cacheobjtype, objtype, text ,query_plan FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text(plan_handle) CROSS APPLY sys.dm_exec_query_plan(plan_handle)
För att denna delning av pf-planer faktiskt ska kunna uppstå måste alla cache-nycklar för planen vara desamma. Förutom att arithabort
själv några andra exempel är de körande användarna behöver samma standardschema (om frågan är beroende av implicit namnupplösning) och anslutningarna behöver samma language
set.
Svar
Jag vet att jag är sen till det här partiet, men för framtida besökare är Martin exakt korrekt. Vi stötte på samma fråga – en SP körde mycket långsamt för .NET-klienter, medan det flammade snabbt för SSMS. För att utforska och lösa problemet gjorde vi den systematiska testningen som Kenny Evitt frågar om i sin kommentar till Martins fråga.
Med en variant av Martins fråga, jag letade efter SP i procedurcachen och hittade två av dem. Med tanke på planerna var det faktiskt så att man hade ARITHABORT PÅ och en hade ARITHABORT OFF. ARITHABORT OFF-versionen hade en indexsökning medan ARITHABORT ON-versionen använde en indexsökning för samma utdata. Med tanke på de parametrar som är inblandade skulle indexsökningen ha krävt tio miljoner poster för utdata.
Jag rensade de två procedurerna från cachen och lät .NET-klienten köra SP igen med hjälp av samma parametrar (som innehöll ett brett datumintervall för en kund med mycket aktivitet). SP återvände direkt. Den cachade planen använde samma indexsökning som tidigare presenterades i ARITHABORT ON-planen – men den här gången var planen för ARITHABORT OFF. Vi körde SP med samma parametrar i SSMS och fick igen resultat direkt. Nu såg vi att en andra plan cachades, för ARITHABORT ON, med indexsökning.
Vi rensade sedan cachen, körde SP i SSMS med ett smalt datumintervall och fick ett omedelbart resultat. Vi fann att den resulterande cachade planen hade en indexsökning, för samma output hanterades tidigare med en skanning (vilket också var en sökning i den ursprungliga planen med ARITHABORT OFF). Återigen från SSMS körde vi SP, den här gången med samma breda datumintervall, och såg samma hemska prestanda som vi hade i den ursprungliga .NET-begäran.
Kort sagt, skillnaden hade inget att göra med det faktiska värdet av ARITHABORT – med det på eller av, från endera klienten, kunde vi få acceptabel eller hemsk prestanda: Allt som betydde var parametervärdena som användes för att sammanställa och cacha planen. id = ”540ca15827”>
MSDN indikerar att ARITHABORT OFF i sig kan ha en negativ inverkan på optimering av frågan, vår testning bekräftar att Martin är korrekt – orsaken var parameter sniffing och den resulterande planen var inte optimal för alla parametrar.
Kommentarer
- Undrar vad den frasen
Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.
betyder. Oavsett om de bara pratar om oförmåga att använda index på beräknade kolumner och vyer (omANSI_WARNINGS
också är av) eller om det verkligen har någon annan effekt. - Jag ’ är inte säker. Jag undrar om det ’ helt enkelt är fallet att någon på MSDN hamnade i en liknande situation, satte ARTIHABORT på ON, såg prestandaförbättringen och hoppade till samma slutsatser som andra har. När det gäller indexerade vyer och beräknade kolumner är jag ’ oklar. Vid ett tillfälle anges att SET-alternativen måste ha specifika värden om en INSERT-, UPDATE- eller DELETE-åtgärd ändrar datavärden som lagras däri. Annars säger de att optimeraren ignorerar index för ” alla frågor ” som refererar till den indexerade vyn eller den beräknade kolumnen. Är båda sanna, eller är det verkligen ” någon fråga som ändrar data ”?
Svar
Hade just detta problem. Som folk sa här är grundorsaken flera frågeplaner, varav en är suboptimal. Jag ville bara verifiera att ARITHABORT verkligen kan orsaka problemet i sig själv (eftersom frågan jag hade problem med hade inga parametrar, vilket tar bort parametersniffning ur ekvationen).
Svar
Detta påminner mig om exakt samma problem som jag upplevde i SQL Server 2008 dagar. I vårt fall hittade vi plötsligt ett sql-jobb plötsligt saktade ner (vanligtvis några sekunder och nu 9+ minuter), jobbet måste komma åt en länkad server, vi lade till att ARITHABORT var på i jobbets steg, och det verkade problemet löstes några dagar och återvände sedan.
Vi öppnade senare en biljett med MS-stöd, och initialt kan de inte heller ta reda på det, och biljetten eskalerades till ett mycket senior PFE-team och två support PFE försökte ta reda på denna fråga.
Den sista anledningen är att användaruppgifterna (för att utföra jobbsteget) inte kan komma åt statistiken för de underliggande tabellerna (på den länkade serversidan), och därmed optimeras inte exekveringsplanen.
I detalj har användaren inte behörighet för DBCC SHOW_STATISTICS (även om användaren kan välja mellan bordet). Enligt MSDN ändras denna behörighetsregel efter SQL 2012 SP1
Behörigheter för SQL Server och SQL Database
För att kunna se statistikobjektet måste användaren äga tabellen eller användaren måste vara medlem i rollen sysadmin fixad server, den fasta databasrollen db_owner eller den fasta databasrollen db_ddladmin.
SQL Server 2012 SP1 ändrar behörighetsbegränsningarna och tillåter användare med SELECT-behörighet att använda detta kommando. Observera att följande krav finns för att SELECT-behörigheter ska vara tillräckliga för att köra kommandot:
För att verifiera det här problemet behöver vi bara köra profilen på den länkade serverns sidinstans och aktivera vissa händelser i ”Fel” och varningar ”avsnitt som visas nedan.
Hoppas att den här upplevelsen kan hjälpa samhället på något sätt.
SET
-alternativ få en bättre plan och feldiagnostisera detta som att det är själva alternativet som är fel. Jag ’ är inte övertygad om att killen i din länk inte har ’ inte gjort detta.