Detta är vad jag har lärt mig hittills från min forskning.
.NET skickar in anslutningsinställningar som inte är desamma som du får när du loggar in på managementstudio. Här är vad du ser om du sniffar kopplingen med SQL Profiler:
-- network protocol: TCP/IP
set quoted_identifier off
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls off
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed
Jag klistrar nu in dessa inställningar ovanför varje fråga som jag kör när jag är inloggad på sql-servern, för att se till att inställningarna är desamma.
I det här fallet provade jag varje inställning individuellt, efter att ha kopplat från och återanslutit, och upptäckte att om jag ändrade arithabort från av till på minskade problemfrågan från 90 sekunder till 1 sekund.
Den mest troliga förklaringen är relaterad till parametersniffning, vilket är en teknik som SQL Server använder för att välja vad den tror är den mest effektiva frågeplanen. När du ändrar en av anslutningsinställningarna kan frågeoptimeraren välja en annan plan, och i det här fallet valde den tydligen en dålig plan.
Men jag är inte helt övertygad om detta. Jag har försökt jämföra de faktiska frågeplanerna efter att ha ändrat den här inställningen och jag har ännu inte sett skillnaden visa några ändringar.
Finns det något annat med arithabort-inställningen som kan göra att en fråga körs långsamt i vissa fall?
Lösningen verkade enkel:Sätt bara på set arithabort i toppen av den lagrade proceduren. Men detta kan leda till det motsatta problemet:ändra frågeparametrarna och plötsligt går det snabbare med 'av' än 'på'.
För närvarande kör jag proceduren "med omkompilering" för att se till att planen återskapas varje gång. Det är ok för just den här rapporten, eftersom det kanske tar en sekund att kompilera om, och detta är inte så märkbart på en rapport som tar 1-10 sekunder att returnera (det är ett monster).
Men det är inte ett alternativ för andra frågor som körs mycket oftare och som behöver återvända så snabbt som möjligt, på bara några millisekunder.