Prestanda för CLR-integreringsarkitektur
gäller för:SQL Server
Azure SQL Managed Instance
I den här artikeln beskrivs några av de designval som förbättrar prestanda för SQL Server-integrering med .NET Framework common language runtime (CLR).
Kompileringsprocessen
När en referens till en hanterad rutin påträffas vid kompilering av SQL-uttryck genereras en vanlig mellanliggande språkstub (CIL). Den här stuben innehåller kod för att konvertera rutinparametrarna från SQL Server till CLR, anropa funktionen och returnera resultatet. Det här limma kod baseras på parametertypen och parameterriktningen (i, uteller referens).
Limkoden möjliggör typspecifika optimeringar och säkerställer effektiv tillämpning av SQL Server-semantik, till exempel nullabilitet, begränsande fasetter, per värde och standardhantering av undantag. Genom att generera kod för de exakta typerna av argument undviker du kostnader för att skapa typtvång eller omslutningsobjekt (kallas "boxning") över anropsgränsen.
Den genererade stuben kompileras sedan till intern kod och optimeras för den specifika maskinvaruarkitektur som SQL Server kör med hjälp av JIT-kompileringstjänsterna (just-in-time) i CLR. JIT-tjänsterna anropas på metodnivå och gör det möjligt för SQL Server-värdmiljön att skapa en enda kompileringsenhet som omfattar både SQL Server- och CLR-körning. När stub har kompilerats blir den resulterande funktionspekaren körningsimplementeringen av funktionen. Den här metoden för kodgenerering säkerställer att det inte finns några extra anropskostnader relaterade till reflektion eller metadataåtkomst vid körning.
Snabba övergångar mellan SQL Server och CLR
Kompileringsprocessen ger en funktionspekare som kan anropas vid körning från inbyggd kod. För skalärvärdesanvändardefinierade funktioner sker den här funktionsanropet per rad. För att minimera kostnaden för övergången mellan SQL Server och CLR har instruktioner som innehåller alla hanterade anrop ett startsteg för att identifiera målprogramdomänen. Det här identifieringssteget minskar kostnaden för övergången för varje rad.
Prestandaöverväganden
I följande avsnitt sammanfattas prestandaöverväganden som är specifika för CLR-integrering i SQL Server. Mer information finns i Använda CLR-integrering i SQL Server 2005. Information om prestanda för hanterad kod finns i Förbättra prestanda för .NET-program och skalbarhet.
Användardefinierade funktioner
CLR-funktioner drar nytta av en snabbare anropssökväg än Transact-SQL användardefinierade funktioner. Dessutom har hanterad kod en avgörande prestandafördel jämfört med Transact-SQL när det gäller procedurkod, beräkning och strängmanipulering. CLR-funktioner som är beräkningsintensiva och som inte utför dataåtkomst skrivs bättre i hanterad kod. Transact-SQL funktioner utför dock dataåtkomst effektivare än CLR-integrering.
Användardefinierade aggregeringar
Hanterad kod kan avsevärt överträffa markörbaserad aggregering. Hanterad kod fungerar vanligtvis något långsammare än inbyggda SQL Server-mängdfunktioner. Vi rekommenderar att du använder den om det finns en inbyggd inbyggd aggregeringsfunktion. I fall där den nödvändiga aggregeringen inte stöds internt bör du överväga en CLR-användardefinierad aggregering över en markörbaserad implementering av prestandaskäl.
Strömmande tabellvärdesfunktioner
Program måste ofta returnera en tabell som ett resultat av att en funktion anropas. Exempel är att läsa tabelldata från en fil som en del av en importåtgärd och konvertera kommaavgränsade värden till en relationsrepresentation. Vanligtvis kan du göra detta genom att materialisera och fylla i resultattabellen innan den kan användas av anroparen. Integreringen av CLR i SQL Server introducerar en ny utökningsmekanism som kallas för en strömmande tabellvärdesfunktion (STVF). Hanterade STVF:er presterar bättre än jämförbara implementeringar av utökade lagrade procedurer.
STVF:er är hanterade funktioner som returnerar ett IEnumerable
-gränssnitt.
IEnumerable
har metoder för att navigera i resultatuppsättningen som returneras av STVF. När STVF anropas är den returnerade IEnumerable
direkt ansluten till frågeplanen. Frågeplanen anropar IEnumerable
metoder när den behöver hämta rader. Med den här iterationsmodellen kan resultatet förbrukas omedelbart efter att den första raden har skapats, i stället för att vänta tills hela tabellen har fyllts i. Det minskar också avsevärt det minne som förbrukas genom att anropa funktionen.
Matriser jämfört med markörer
När Transact-SQL markörer måste bläddra igenom data som är enklare att uttrycka som en matris kan hanterad kod användas med betydande prestandavinster.
Strängdata
SQL Server-teckendata, till exempel varchar, kan vara av typen SqlString
eller SqlChars
i hanterade funktioner.
SqlString
variabler skapar en instans av hela värdet i minnet.
SqlChars
variabler ger ett direktuppspelningsgränssnitt som kan användas för att uppnå bättre prestanda och skalbarhet genom att inte skapa en instans av hela värdet i minnet. Detta blir viktigt för stora objektdata (LOB). Dessutom kan du komma åt XML-serverdata via ett direktuppspelningsgränssnitt som returneras av SqlXml.CreateReader()
.
CLR jämfört med utökade lagrade procedurer
De Microsoft.SqlServer.Server
API:er (Application Programming Interface) som gör att hanterade procedurer kan skicka resultatuppsättningar tillbaka till klienten presterar bättre än DE ODS-API:er (Open Data Services) som används av utökade lagrade procedurer. Dessutom stöder System.Data.SqlServer
API:er datatyper som xml, varchar(max), nvarchar(max)och varbinary(max), medan ODS-API:erna inte har utökats för att stödja dessa datatyper.
Med hanterad kod hanterar SQL Server användning av resurser som minne, trådar och synkronisering. Det beror på att de hanterade API:er som exponerar dessa resurser implementeras ovanpå SQL Server-resurshanteraren. Omvänt har SQL Server ingen vy eller kontroll över resursanvändningen för den utökade lagrade proceduren. Om en utökad lagrad procedur till exempel förbrukar för mycket PROCESSOR- eller minnesresurser finns det inget sätt att identifiera eller kontrollera detta med SQL Server. Med hanterad kod kan DOCK SQL Server identifiera att en viss tråd inte har gett under en längre tid och sedan tvinga aktiviteten att ge resultat så att annat arbete kan schemaläggas. Med hanterad kod får du därför bättre skalbarhet och systemresursanvändning.
Hanterad kod kan medföra extra kostnader som krävs för att underhålla körningsmiljön och utföra säkerhetskontroller. Detta är till exempel fallet när du kör i SQL Server och många övergångar från hanterad till intern kod krävs (eftersom SQL Server måste utföra extra underhåll på trådspecifika inställningar när du flyttar ut till intern kod och tillbaka). Utökade lagrade procedurer kan därför avsevärt överträffa hanterad kod som körs i SQL Server för fall där det sker frekventa övergångar mellan hanterad och intern kod.
Not
Utveckla inte nya utökade lagrade procedurer eftersom den här funktionen är inaktuell.
Intern serialisering för användardefinierade typer
Användardefinierade typer (UDT) är utformade som en utökningsmekanism för skalära typsystem. SQL Server implementerar ett serialiseringsformat för UDT:er som kallas Format.Native
. Under kompilering granskas strukturen för typen för att generera CIL som är anpassad för den specifika typdefinitionen.
Intern serialisering är standardimplementeringen för SQL Server. Användardefinierad serialisering anropar en metod som definierats av typförfattaren för att utföra serialiseringen.
Format.Native
serialisering bör användas när det är möjligt för bästa prestanda.
Normalisering av jämförbara UDT
Relationsåtgärder, till exempel sortering och jämförelse av UDT: er, fungerar direkt på den binära representationen av värdet. Detta uppnås genom att lagra en normaliserad (binär ordnad) representation av udt-tillståndet på disken.
Normalisering har två fördelar:
Det gör jämförelseåtgärden betydligt billigare genom att undvika konstruktionen av typinstansen och metodens anropskostnader.
Den skapar en binär domän för UDT, vilket gör det möjligt att skapa histogram, index och histogram för värden av typen.
Normaliserade UDT:er har därför en liknande prestandaprofil som de inbyggda inbyggda typerna för åtgärder som inte omfattar metodanrop.
Skalbar minnesanvändning
Undvik stor, enkel allokering för att hanterad skräpinsamling ska fungera och skalas bra i SQL Server. Allokeringar som är större än 88 kilobyte (KB) placeras på Heap för stora objekt, vilket gör att skräpinsamlingen presterar och skalas sämre än många mindre allokeringar. Om du till exempel behöver allokera en stor flerdimensionell matris är det bättre att allokera en ojämn (utspridd) matris.