sql >> Databasteknik >  >> RDS >> Database

Knee-Jerk Wait Statistik :CXPACKET

I flera av mina inlägg under det senaste året har jag använt temat att människor ser en viss typ av väntetid och sedan reagerar på ett "knee-jerk"-sätt på att väntan är där. Vanligtvis innebär det att man följer några dåliga råd på Internet och vidtar en drastisk, olämplig åtgärd eller drar en slutsats om vad som är grundorsaken till problemet och sedan slösar tid och ansträngning på en vilda jakt.

En av de väntetyper där knästötsreaktionerna är starkast, och där några av de sämsta råden finns, är CXPACKET-väntan. Det är också väntetypen som oftast är den bästa väntetiden på folks servrar (enligt mina två stora undersökningar av väntetyper från 2010 och 2014 – se här för detaljer), så jag kommer att ta upp det i det här inlägget.

Vad betyder väntetypen CXPACKET?

Den enklaste förklaringen är att CXPACKET betyder att du har frågor som körs parallellt och att du *alltid* ser att CXPACKET väntar på en parallell fråga. CXPACKET-väntningar betyder INTE att du har problematisk parallellitet – du måste gräva djupare för att avgöra det.

Som ett exempel på en parallell operatör, betrakta operatören Repartition Streams, som har följande ikon i grafiska frågeplaner:

Och här är en bild som visar vad som händer i termer av parallella trådar för den här operatören, med graden av parallellism (DOP) lika med 4:

För DOP =4 kommer det att finnas fyra producenttrådar som hämtar data från tidigare i frågeplanen, data går sedan tillbaka till resten av frågeplanen genom fyra konsumenttrådar.

Du kan se de olika trådarna i en parallelloperator som väntar på en resurs med hjälp av sys.dm_os_waiting_tasks DMV, i exec_context_id kolumn (det här inlägget har mitt manus för att göra detta).

Det finns alltid en 'kontroll'-tråd för alla parallella planer, som av en historisk slump alltid är tråd-ID 0. Kontrolltråden registrerar alltid en CXPACKET-väntetid, med varaktigheten lika med hur lång tid planen tar att genomföra. Paul White har en bra förklaring av trådar i parallella planer här.

Den enda gången som icke-kontrollerade trådar kommer att registrera CXPACKET-väntningar är om de slutförs före de andra trådarna i operatören. Detta kan hända om en av trådarna fastnar och väntar på en resurs under en längre tid, så titta för att se vad väntetypen är för tråden som inte visar CXPACKET (med mitt skript ovan) och felsök på lämpligt sätt. Detta kan också hända på grund av en skev arbetsfördelning bland trådarna, och jag kommer att gå in mer på det fallet i mitt nästa inlägg här (det orsakas av inaktuell statistik och andra problem med uppskattning av kardinalitet).

Observera att i SQL Server 2016 SP2 och SQL Server 2017 RTM CU3 registrerar inte längre konsumenttrådar CXPACKET-väntningar. De registrerar CXCONSUMER-väntningar, som är godartade och kan ignoreras. Detta för att minska antalet CXPACKET-väntningar som genereras, och de återstående är mer sannolikt att de kan åtgärdas.

Oväntad parallellism?

Med tanke på att CXPACKET helt enkelt betyder att du har parallellism som händer, är det första du ska titta på om du förväntar dig parallellitet för frågan som använder den. Min fråga kommer att ge dig frågeplanens nod-ID där parallelliteten sker (den drar ut nod-ID:t från XML-frågeplanen om väntetypen för tråden är CXPACKET) så leta efter det nod-ID:t och avgör om parallellismen är vettig .

Ett av de vanligaste fallen av oväntad parallellism är när en tabellskanning sker där du förväntar dig en mindre indexsökning eller -skanning. Du kommer antingen att se detta i frågeplanen eller så ser du massor av PAGEIOLATCH_SH-väntningar (diskuterat i detalj här) tillsammans med CXPACKET-väntningar (ett klassiskt väntestatistikmönster att hålla utkik efter). Det finns en mängd olika orsaker till oväntade tabellskanningar, inklusive:

  • Icke-klustrade index saknas så en tabellsökning är det enda alternativet
  • Inaktuell statistik så att frågeoptimeraren anser att en tabellsökning är den bästa dataåtkomstmetoden att använda
  • En implicit omvandling, på grund av en datatypsfel mellan en tabellkolumn och en variabel eller parameter, vilket innebär att ett icke-klustrat index inte kan användas
  • Aritmetik utförs på en tabellkolumn istället för en variabel eller parameter, vilket innebär att ett icke-klustrat index inte kan användas

I alla dessa fall dikteras lösningen av vad du finner grundorsaken vara.

Men vad händer om det inte finns något uppenbart rotfall och frågan bara bedöms vara tillräckligt dyr för att motivera en parallell plan?

Förhindra parallellism

Bland annat beslutar frågeoptimeraren att producera en parallell frågeplan om serieplanen har en högre kostnad än cost threshold for parallelism , en sp_configure-inställning för instansen. Kostnadströskeln för parallellism (eller CTFP) är inställd på fem som standard, vilket innebär att en plan inte behöver vara särskilt dyr för att utlösa skapandet av en parallell plan.

Ett av de enklaste sätten att förhindra oönskad parallellism är att öka CTFP till ett mycket högre antal, med ju högre du ställer in den, desto mindre sannolikt kommer parallella planer att skapas. Vissa människor förespråkar att sätta CTFP till någonstans mellan 25 och 50, men som med alla inställningar som kan justeras är det bäst att testa olika värden och se vad som fungerar bäst för din miljö. Om du vill ha en lite mer programmatisk metod för att hjälpa dig att välja ett bra CTFP-värde, skrev Jonathan ett blogginlägg som visade en fråga för att analysera planens cache och producera ett föreslaget värde för CTFP. Som exempel har vi en klient med CTFP inställd på 200 och en annan inställd på maximalt – 32767 – som ett sätt att med tvång förhindra all parallellism.

Du kanske undrar varför den andra klienten var tvungen att använda CTFP som en släggametod för att förhindra parallellism när du skulle tro att de helt enkelt kunde ställa in serverns "maxgrade of parallelism" (eller MAXDOP) till 1. Tja, alla med vilken behörighetsnivå som helst kan ange en fråga MAXDOP-tips och åsidosätt serverns MAXDOP-inställning, men CTFP kan inte åsidosättas.

Och det är en annan metod för att begränsa parallellitet – att ställa in en MAXDOP-tips på frågan som du inte vill ska gå parallellt.

Du kan också sänka serverns MAXDOP-inställning, men det är en drastisk lösning eftersom det kan förhindra att allt använder parallellism. Det är vanligt nuförtiden att servrar har blandade arbetsbelastningar, till exempel med vissa OLTP-frågor och vissa rapporteringsfrågor. Om du sänker serverns MAXDOP kommer du att hämma prestandan för rapporteringsfrågorna.

En bättre lösning när det finns en blandad arbetsbelastning skulle vara att använda CTFP som jag beskrev ovan eller att använda Resource Governor (vilket är Enterprise-only, är jag rädd). Du kan använda Resource Governor för att dela upp arbetsbelastningarna i arbetsbelastningsgrupper och sedan ställa in en MAX_DOP (understrecket är inte ett stavfel) för varje arbetsbelastningsgrupp. Och det som är bra med att använda Resource Governor är att MAX_DOP inte kan åsidosättas av ett MAXDOP-frågetips.

Sammanfattning

Gå inte i fällan att tro att CXPACKET väntar automatiskt betyder att du har dålig parallellism, och följ absolut inte några av internetråden jag har sett om att slå igen servern genom att sätta MAXDOP på 1. Ta dig tid för att undersöka varför du ser att CXPACKET väntar och om det är något som ska åtgärdas eller bara en artefakt av en arbetsbelastning som körs korrekt.

När det gäller allmän väntestatistik kan du hitta mer information om hur du använder dem för prestandafelsökning i:

  • Min SQLskills blogginläggsserie, som börjar med Vänta statistik, eller snälla berätta för mig var det gör ont
  • Mina väntetyper och låsklasser-bibliotek här
  • Min Pluralsight onlinekurs SQL Server:Prestandafelsökning med hjälp av väntastatistik
  • SQL Sentry Performance Advisor

I nästa artikel i serien kommer jag att diskutera skev parallellitet och ge dig ett enkelt sätt att se det hända. Tills dess, glad felsökning!


  1. Använder JShell i Java 9 i NetBeans 9.0, del 4

  2. Hur man räknar antalet rader i en tabell i SQL

  3. ORA-28040:Inget matchande undantag för autentiseringsprotokoll

  4. Lagra en fil i en databas i motsats till filsystemet?