Brent Ozar, Microsoft Certified Master diskuterade nyligen parallellism i SQL Server, specifikt väntetyperna CXPACKET och CXCONSUMER i sin sista del av Quest’s Database Training Days Fall Series. På sitt vanliga humoristiska och lättillgängliga sätt avmystifierade Brent begreppen parallellism och förklarade hur man hanterar det när man ser för mycket CXPACKET- och CXCONSUMER-väntestatistik.
För det första, vad är parallellism, och varför får SQL Server frågor att köras parallellt?
Enkelt uttryckt känner SQL Server automatiskt igen att en viss fråga har en stor arbetsbelastning och den avgör att arbetet kan utföras mer effektivt över flera processorer än med bara en. Detta är i allmänhet ett smart beslut, men det kan hamna i problem när SQL Server inte balanserar belastningen över de trådar som utför uppgiften.
Förstå väntetyperna CXPACKET och CXCONSUMER
CXPACKET och CXCONSUMER är väntetyper som indikerar att arbetet inte är lika balanserat. När du ser denna väntestatistik på din server vet du att SQL Server kör frågor parallellt, men inte gör ett bra jobb med att distribuera dem över tillgängliga processorer.
Varje databasproffs är bekant med begreppet "kostnad" för att uttrycka hur dyr en fråga är att utföra när det gäller resursförbrukning. Dessa "frågepengar" är ett ungefärligt mått på arbete och en viktig signal om huruvida frågan kommer att köras parallellt eller inte. En billig fråga behöver inte köras parallellt, men en dyr fråga. Målet är att köra frågan så snabbt och effektivt som möjligt så att nästa i raden kan börja. SQL Server utser en tråd som en schemaläggare, och den här tråden, som Brent ansåg vara "robotens överherre", kommer att tilldela delar av den parallella arbetsbelastningen till arbetartrådarna, eller "robotunderhållarna".
Parallellism och robotens överherre
Brent dyker in i en demo för att visa hur det här fungerar. Med hjälp av Stack Overflow-databasen skapade han en lågkostnadsdatabassökning som var mycket snabb på grund av närvaron av ett index. Utförandeplanen var ganska enkel och krävde inte parallellitet för att köras.
Men när han introducerade en uppslagning för något som inte fanns i indexet förändrades saker genom att tvinga fram en nyckeluppslagning för varje rad i tabellens klustrade index. SQL Server insåg att detta skulle vara mycket arbete, så den introducerade parallellism och indikerade som sådan med en ikon på exekveringsplanen. Om exekveringsplanen var tredimensionell skulle du kunna se flera trådar staplade, men eftersom det inte är det måste du se statistiken för att se information som de logiska läsningarna som utförs av varje CPU-tråd.
SQL Server tilldelade dock bara denna uppgift till ett fåtal trådar, inte alla. Brent förklarade att allt som händer bortom parallellikonen bara händer på de tilldelade processorerna. Så trådarna som utförde de första läsningarna är nu de enda som också gör nyckelsökningarna. Robotöverherren bad bara ett fåtal hantlangar att utföra hela uppgiften istället för att be alla hantlangarna att ställa upp.
Han fortsatte med att förklara att SQL Server måste redogöra för vad trådarna gör samt spåra vad robotöverherren gör. Under de första dagarna representerades allt detta arbete av en väntestatistik, men detta var inte vettigt för oavsett vad måste överherren fortfarande vänta medan alla trådar fungerar. Så en ny väntetyp introducerades – det här var CXCONSUMER och den spårar vad schemaläggaren/overlord-tråden gör, medan CXPACKET spårar vad arbetar-/miniontrådarna gör.
Brent gick tillbaka till frågan för att göra den ännu mer komplex genom att lägga till en sortering. Nu blir det ännu tydligare att parallellitet orsakar ett problem snarare än att göra verksamheten mer effektiv. Arbetet har blivit ännu mer obalanserat över de få arbetartrådarna, och vissa har slut på minne och rinner ut på disken. Han lade till en anslutning, vilket ytterligare belastade de arbetande kärnorna som inte får någon hjälp från de icke-arbetande. CXPACKET-statistiken fortsatte att klättra.
Vad kan du göra i den här situationen? Beslutet om parallellitet sker på servernivå och inte på frågenivå, så det kommer att kräva några konfigurationsändringar.
Bedöma nyckelkonfigurationer
Vi har redan lärt oss att om frågekostnaden är högre än en viss nivå, får det SQL Server att parallelliseras. Små frågor begränsas till en enda tråd. Men vad styr tröskeln? Det är en egenskap som heter Cost Threshold for Parallelism (CTFP). Som standard, om exekveringsplanen bestämmer att kostnaden är högre än 5 frågedollar, kommer frågan att parallelliseras. Även om det inte finns någon vägledning om hur man ställer in detta, rekommenderar Brent ett antal större än 50. Detta kommer att ta bort parallellism för triviala frågor.
En annan konfiguration är maxgraden av parallellism (MAXDOP) som beskriver antalet trådar som SQL Server kommer att tilldela frågan. Standardvärdet här är noll, vilket innebär att SQL Server kan använda alla tillgängliga processorer, upp till 64, för att köra frågan. Att ställa in MAXDOP-alternativet till 1 begränsar SQL Server till att endast använda en processor – i själva verket tvingar en seriell plan att exekvera frågan. SQL Server kommer att rekommendera ett MAXDOP-värde baserat på antalet serverkärnor du har, men i allmänhet är ett lägre MAXDOP vettigt eftersom det inte kommer att finnas många gånger som alla kärnor behövs.
Brent gjorde justeringar av dessa två konfigurationer och körde sin fråga igen. Den här gången kunde vi se att fler kärnor var engagerade i den parallella operationen. Väntestatistiken för CXPACKET var lägre vilket innebar att belastningen var mer jämnt balanserad över fler kärnor än tidigare.
Tips för att bekämpa CXPACKET och CXCONSUMER väntestatistik
Brent rekommenderar följande steg om du ser överdriven CXPACKET och CXCONSUMER väntestatistik:
- Ställ in CTFP och MAXDOP per bransch bästa praxis och låt sedan dessa inställningar baka i några dagar. Detta rensar planens cache och tvingar SQL Server att bygga om planer för körning av frågor (omvärdera kostnaden).
- Gör indexförbättringar som minskar antalet gånger då frågor går parallellt för att göra skanningar och sorteringar. Låt nya index bakas och leta sedan efter frågor som fortfarande gör mycket arbete.
- Justera dessa frågor och låt dem grädda i några dagar.
- Slutligen, om parallellism fortfarande är ett allvarligt problem, börja leta efter de specifika frågorna med parallellitetsproblem.
För ännu mer insikt kan du fånga Brents hela träningspass på CXPACKET och CXCONSUMER väntestatistik på begäran nedan.