Varför en pratsam SQL-app kryper över VPN och vad du bör gruppera
En skärm som avlossar hundra beroende frågor betalar rundturen hundra gånger. Räkna väntetiderna, gruppera de oberoende och flytta sedan körningen.
Ett formulär som öppnas på under en sekund i ett lokalt nätverk tar fem sekunder över VPN, medan en filkopia på samma länk går i full hastighet. Skillnaden är inte bandbredd. Formuläret väntar på en sekvens av svar och betalar hela rundturen vid varje steg, medan filkopian håller byte kontinuerligt i rörelse. Räkna de väntetiderna innan du rör accesslinjen.
Symtomet är en skärm, inte en fråga
Varje fråga på den skärmen kan vara snabb och skärmen kan ändå vara långsam, eftersom summan är summan av väntetider och inte summan av körtider. Ett uttalande som körs på två millisekunder kostar fortfarande en hel rundtur när klienten måste ta emot resultatet innan den skickar nästa. På en väg med fyrtio millisekunders latens summerar hundra beroende anrop till ungefär fyra sekunder innan något renderingsarbete sker. Den aritmetiken är en modell av väntan, inte en mätning av din länk.
Det är därför ett hastighetstest ser oskyldigt ut. Bulköverföring mäter genomströmning, ett pratsamt formulär mäter latens, och en VPN kan vara utmärkt på det ena och ändå helt vanlig på det andra. Att diagnostisera skärmen innebär därför att mäta skärmen och inte länken.
Registrera tiden från början till slut för en användaråtgärd innan du ändrar något. Den siffran är den enda baslinje som kan säga om en senare åtgärd fungerade.
Räkna sekventiella väntetider i en användaråtgärd
Instrumentera klienten i stället för att gissa. I psql skriver \timing on ut förfluten tid för varje uttalande, och EXPLAIN (ANALYZE, BUFFERS) visar hur mycket av den tiden servern faktiskt lade på arbetet.
Gapet mellan de två siffrorna är din nätverks- och klientkostnad. Om ett uttalande körs på två millisekunder och klienten registrerar sextio, är de återstående femtioåtta resa och lokal bearbetning, och inget index tar bort dem. Upprepa jämförelsen för varje uttalande som skärmen skickar och summera gapen i stället för körtiderna.
Skriv ner resultatet som ett antal sekventiella väntetider. Det är den storhet som de två följande avsnitten kan minska, och det är en siffra du kan argumentera om med bevis.
Gruppera de oberoende anropen, behåll de beroende
Två uttalanden som inte läser varandras resultat kan resa tillsammans och hämtas en gång, vilket gör två väntetider till en. Två uttalanden där det andra behöver värdet från det första kan inte, eftersom beroendet är verkligt och gruppering skulle ändra vad programmet gör. Sortera anropen i de två högarna innan du skriver om något, och storleken på varje hög säger vad som är möjligt.
Mängdbaserat arbete tar bort väntetider grundligare än gruppering. En fråga som returnerar raderna som en loop hämtade en i taget eliminerar både loopen och rundturerna. Leta efter loopen först, eftersom den oftast är den största vinsten och den enklaste ändringen att granska.
En grupp måste fortfarande bevara felhantering och transaktionsgränser. Att sammanfoga orelaterade uttalanden till en enda sträng är inte en säker optimering, och en grupp som gömmer ett misslyckat uttalande bakom en lyckad inskickning är sämre än väntetiderna den sparade.
Återanvänd anslutningar innan du köper bandbredd
En ny anslutning kostar namnsuppslagning, TCP-handskakning, TLS-förhandling och autentisering, och på en väg med hög latens är var och en av dem ännu en rundtur innan den första frågan körs. Anslutningspooler finns för att betala den kostnaden en gång per process i stället för en gång per anrop.
I ADO.NET lämnar stängning eller dispose av en poolad anslutning tillbaka den för återanvändning i stället för att öppna en ny fysisk, så mönstret som ser ut som en läcka är ofta korrekt användning. Verifiera att poolen verkligen används i stället för att anta det: logga skapandet av fysiska anslutningar eller följ sessionsantalet på servern medan skärmen körs. Riktlinjerna för SQL-prestanda säger samma sak om att minska rundturer och gruppera täta ad hoc-anrop, med tjänstespecifika exempel som du bör koppla till din egen distribution.
Poolning tar bort etableringskostnaden och lämnar de sekventiella frågeväntetiderna orörda. Det är en förutsättning för en ren mätning, inte en åtgärd i sig.
Väg att flytta körningen närmare data
Att köra applikationen nära databasen ersätter många fjärrutbyten med databasen med en enda fjärrvisningssession. För en pratsam arbetsbelastning kan det vara en stor förändring, och det är en driftsförändring lika mycket som en prestandaförändring: sessionshantering, åtkomstkontroll, programvarudistribution och användarupplevelse flyttar alla med applikationen.
Mät det faktiska gränssnittet och de data det överför innan du antar att någon riktning är snabbare. En fjärrskrivbordssession flyttar pixlar, och en skärm med tät grafik kan prestera sämre över samma väg än frågorna den ersatte, särskilt när klienten ritar om kontinuerligt.
Upprepa sedan den ursprungliga åtgärden och jämför tre siffror: sekventiella väntetider, resultatvolym och slutförandetid från början till slut. En förbättring som ändrar den uppmätta användaruppgiften medan den bevarar datakorrekthet och åtkomstpolicy är den som är värd att behålla.