In mijn laatste bericht, "Meerdere plannen voor een 'identieke' zoekopdracht", heb ik gesproken over het geval waarin u twee verschillende plannen krijgt voor wat u denkt dat dezelfde vraag is, evenals het geval waarin u twee exemplaren van de hetzelfde plan (en weet het misschien niet eens). Zoals we daar hebben onderzocht, kan 'identiek' een behoorlijk sterk woord zijn.
Een ander scenario dat mensen in de war brengt, is het geval waarin ze een database terugzetten naar een andere server, bijvoorbeeld een productiedatabase terugzetten naar een "identieke" testserver, en ze verschillende prestatiekenmerken of verschillende plannen krijgen voor dezelfde query (geen citaten deze keer - ik heb het echt over echt identieke zoekopdrachten).
Zijn de servers echt "identiek"?
Deze jongens lijken misschien op elkaar, maar ze zijn niet helemaal identiek.Als je dit scenario tegenkomt, is het eerste dat je jezelf moet afvragen of deze twee servers echt identiek zijn. Enkele dingen om te controleren:
- Versie – Veel wijzigingen in het optimalisatie- en querygedrag worden via servicepacks en cumulatieve updates doorgevoerd. Vaak heb ik mensen zien zeggen:"Nou, ze zijn allebei 2008!" – terwijl de ene in feite 2008 was en de andere 2008 R2, of ze hadden verschillende servicepacks of zelfs cumulatieve updateniveaus. Aangezien veel mensen die @@VERSION lezen de servicepack-informatie van het besturingssysteem verwarren met de informatie over het SQL Server-servicepack, zou ik zeggen dat het volgende beter is:
SELECT
SERVERPROPERTY
(N'ProductVersion'
);Ik kan niet genoeg benadrukken hoe belangrijk het is om exact dezelfde versie te gebruiken om echte appels-tot-appels-tests uit te voeren. Als u SQL Server 2012 of beter gebruikt, kunt u onze buildberichten (SQL Server 2012 | SQL Server 2014) raadplegen om te bepalen welk servicepack of cumulatieve update vereist is om te controleren of de versies overeenkomen.
- Editie – Hoewel u hopelijk dezelfde editie op beide servers gebruikt (of gelijkwaardig, aangezien naast licenties, Ontwikkelaar en Evaluatie hetzelfde zijn als Enterprise), kunnen mismatches hier leiden tot heel ander gedrag. Verschillende edities hebben bijvoorbeeld verschillende rekencapaciteiten voor verschillende functies, en dan zijn er subtielere dingen zoals de mogelijkheid om een geïndexeerde weergave te gebruiken zonder de NOEXPAND-hint of om schemawijzigingen of indexonderhoud online uit te voeren. U kunt edities vergelijken met:
SELECT
SERVERPROPERTY
(N'Edition'
); - CPU-telling – SQL Server gebruikt absoluut het aantal beschikbare planners tijdens het maken van een uitvoeringsplan, en het valt niet te ontkennen dat het aantal kernen de werkelijke runtime-prestaties kan beïnvloeden (laten we de kloksnelheid weglaten, aangezien dat zelden een belangrijke factor is bij het zoeken uitvoering). Valideer niet alleen het aantal cores dat fysiek in de onderliggende server is geïnstalleerd, maar controleer ook het foutenlogboek van SQL Server voor het aantal CPU's dat SQL Server daadwerkelijk kan gebruiken vanwege licenties. Zelfs als we het ruwe aantal kernen vergeten, op een NUMA-systeem, kunnen kunstmatige beperkingen hier leiden tot zeer verschillende prestatieprofielen. Zie voor meer informatie het recente bericht van Brent Ozar, "Why Core-Based Licensing Matters for Performance Tuning." Edition sluit hier ook bij aan, aangezien Standard Edition in SQL Server 2012 en 2014 slechts 16 cores kan gebruiken, ongeacht wat uw instellingen of fysieke hardware u misschien doen geloven. Andere instellingen die de keuze en prestaties van CPU-gebaseerde plannen op een andere manier kunnen beïnvloeden, zijn onder meer Resource Governor, serverbrede MAXDOP, CPU-affiniteit en kostendrempel voor parallellisme.
- Hoeveelheid geheugen – Net als CPU's maakt de optimizer plankeuzes op basis van de hoeveelheid beschikbaar geheugen. En net als CPU's, heb ik het niet alleen over de hoeveelheid RAM die in het systeem is geïnstalleerd, maar ook over de hoeveelheid geheugen die aan SQL Server is toegekend en hoeveel het werkelijk gebruikt. Controleer de maximale servergeheugeninstellingen, maar ook de prestatietellers voor totaal- en doelgeheugen, en zelfs DBCC MEMORYSTATUS. Andere dingen die u misschien wilt bekijken, zijn onder meer de instellingen van de bronbeheerder en de pagina's vergrendelen in het geheugen. Er is ook een instelling die, als deze tussen twee servers verschilt, een aanzienlijk effect kan hebben op hoeveel van de plancache wordt gebruikt voor dezelfde reeks query's:optimaliseren voor ad-hocworkloads. Kimberly Tripp heeft hier een geweldige post over:Plan cache en optimaliseer voor adhoc workloads. Als de server virtueel is, houd er dan rekening mee dat de omgeving hier een rol kan spelen, vooral wanneer de VM-geheugeninstellingen niet overeenkomen met de productie of dynamisch zijn.
- Bufferpool / plancache – Wanneer u de database op de testserver herstelt, zijn er een heleboel dingen die gewoon niet meteen voor u klaar staan. De bufferpool bevat geen van de gegevens die mogelijk op de bronserver hebben gestaan - dus er zal extra I/O nodig zijn om de gegevens in het geheugen te primen wanneer deze voor het eerst worden opgevraagd. En als de bufferpool vanwege een aantal van de bovenstaande factoren anders wordt beperkt dan de productie, is het misschien niet mogelijk om dezelfde prestatiepatronen te bereiken, zelfs niet nadat de query meerdere keren is uitgevoerd - Paul White (@SQL_Kiwi) vertelt hierover in zijn antwoord op Databasebeheerders. Ook bevat de plancache geen van de plannen die in productie waren, dus op zijn minst - zelfs als hetzelfde plan uiteindelijk wordt gecompileerd (wat mogelijk niet gebeurt vanwege andere parameters dan toen het plan werd samengesteld op het origineel server) – u heeft extra compilatiekosten. En die kunnen veranderen als je ook traceervlaggen hebt die van invloed zijn op het plan.
- Schijfsubsysteem – Hoewel de snelheid en grootte van de gebruikte schijf(ken) niet direct van invloed zijn op de keuze van het abonnement, kunnen ze zeker de waargenomen prestaties beïnvloeden, waardoor je je af kunt vragen waarom dezelfde query, met hetzelfde abonnement, zoveel sneller op één wordt uitgevoerd systeem dan het andere. I/O is typisch het grootste knelpunt van SQL Server, en het is vrij zeldzaam dat een testserver echt exact hetzelfde onderliggende subsysteem heeft als zijn productie-equivalent. Dus als u prestatieverschillen tussen de twee systemen ziet en de plannen en andere hardware-elementen hetzelfde zijn, is dit misschien de volgende beste plaats om te controleren. En vergeet niet dat Resource Governor vanaf SQL Server 2014 beperkingen kan stellen aan uw I/O-prestaties.
- Vlaggen traceren – Controleer de lijst met globale traceervlaggen die op beide servers zijn ingesteld; er zijn er verschillende die van invloed kunnen zijn op optimalisatie, plangedrag en waargenomen prestaties, zelfs als alle bovenstaande instellingen identiek zijn. Hier zijn 10 veelvoorkomende en opvallende (hoewel dit absoluut geen goedkeuring is om een van deze aan te zetten zonder grondige regressietests):
Vlag Uitleg 2301 Dwingt de optimizer om meer tijd te besteden aan het zoeken naar een optimaal plan. 2312 Dwingt de nieuwe kardinaliteitsschatter van SQL Server 2014 af. 2335 Veroorzaakt meer conservatieve geheugentoelagen. 2453 Forceert OPTIE (RECOMPILE) voor zoekopdrachten die verwijzen naar tabelvariabelen. 2861 Hiermee kan SQL Server triviale / kostenloze plannen in de cache opslaan. 4136 Voegt effectief OPTIMIZE FOR UNKNOWN toe aan alle zoekopdrachten (om het snuiven van parameters te dwarsbomen). 4199 Een paraplu met een hele reeks optimalisatieoplossingen. 8744 Vooraf ophalen van geneste lussen uitschakelen. 9481 Zet de nieuwe kardinaliteitsschatter van SQL Server 2014 uit.
Die lijst met traceervlaggen is zeker niet uitputtend; er zijn er nog veel meer, waaronder mensen zonder papieren waarvan ik heb gevraagd om ze niet te noemen. Als u andere gebruikt die hierboven niet zijn vermeld (en niet kunt uitleggen waarom), vindt u mogelijk aanwijzingen in KB #920093, KB #2964518, Trace Flags (MSDN) of Trace Flags in SQL Server (TechNet). Je zult ook waardevol inzicht vinden in verschillende berichten van Paul White, hier of op sql.kiwi. - Gelijktijdigheid – Vermoedelijk wordt het testsysteem gebruikt voor andere dingen dan wat je momenteel aan het testen bent. En tenzij u een soort herhaling uitvoert, heeft deze waarschijnlijk ook een heel ander werklastprofiel. Deze verschillen in werkbelasting kunnen uiteraard een directe invloed hebben op de beschikbaarheid van resources om de aanvragen die u test te verwerken, en op hun beurt de waargenomen prestaties van die aanvragen. Vergeet niet te controleren op andere services die mogelijk niet in productie zijn, of bestaan maar op verschillende manieren worden gebruikt (zoals Analysis Services, Reporting Services, Windows-services en zelfs uw eigen applicaties). Omgekeerd kunnen er services zoals deze in productie zijn die de prestaties daar beïnvloeden, of extra overhead op de instance zelf die niet wordt nagebootst in de test:denk naast de daadwerkelijke productiebelasting aan zaken als tracering, uitgebreide gebeurtenissen, high-impact monitoring, het bijhouden van wijzigingen, het vastleggen van wijzigingsgegevens, auditing, servicebroker, indexonderhoud, back-uptaken, DBCC-controles, spiegeling, replicatie, beschikbaarheidsgroepen, en de lijst gaat maar door...
Zijn de databases nog steeds "identiek"?
Ervan uitgaande dat alle hardware- en werkbelastingvariabelen goed genoeg overeenkomen, kan het nog steeds een uitdaging zijn om ervoor te zorgen dat de databases hetzelfde blijven. Als u een back-up / herstel uitvoert op het testsysteem, begint de nieuwe database als identiek aan de bron (behalve voor fysieke locatie en beveiliging). Maar zodra je het op een of andere manier begint aan te raken, wijkt het heel snel af van de productiekopie, aangezien je een of meer van de volgende dingen kunt doen:
- Wijzig gegevens, schema of beide.
- Onbedoeld een automatische update van statistieken starten.
- Handmatig indexen toevoegen, defragmenteren of opnieuw opbouwen, of statistieken maken of bijwerken.
- Wijzig database-instellingen zoals compatibiliteitsniveau, isolatieniveau, geforceerde parametrering, selectieve XML-indexen of een van de opties met de naam "Auto"-
. (O ja, zelfs de locatie van gegevens en logbestanden en instellingen voor groei kunnen de prestaties van query's beïnvloeden, en dit geldt ook voor tempdb.) - Leeg de plancache, de bufferpool of beide, direct of als neveneffect van andere gebeurtenissen (zoals HERCONFIGUREREN of het opnieuw opstarten van een service).
Als u eenmaal nieuwe queryplannen begint te genereren, zelfs voordat een van de bovenstaande wijzigingen plaatsvindt, moet u er rekening mee houden dat deze mogelijk zijn gebaseerd op gegevens die anders zijn dan de gegevens die worden gebruikt om plannen voor dezelfde query's in productie te genereren. Als voorbeeld, kardinaliteit toen het plan in productie werd opgesteld, kan aanzienlijk scheef zijn tussen dat punt en het tijdstip van de back-up, wat betekent dat het nieuwe plan zal worden gegenereerd op basis van verschillende statistieken en histograminformatie.
Deze zaken lopen nog verder uiteen als dit in feite geen recent herstel is, maar eerder twee schema's en gegevenssets die u op andere manieren gesynchroniseerd houdt (zoals handmatige implementatie van schema- en/of gegevenswijzigingen, of zelfs replicatie). Vanwege schijfruimtebeperkingen hebt u mogelijk ook slechts een subset van productiegegevens genomen, of zelfs een kloon met alleen statistieken - deze verschillen in gegevens zullen vrijwel zeker leiden tot verschillende prestatiekenmerken voor alle behalve de eenvoudigste query's, zelfs als u dat doet succes en krijg voor sommigen dezelfde plannen.
Zijn de zoekopdrachten echt "identiek"?
Zelfs als alles hierboven klopt, zijn er nog steeds scenario's waarin u een ander abonnement krijgt vanwege sessie-instellingen (mogelijk gebruikt u een ander exemplaar van SSMS, met andere instellingen of een totaal andere clienttool), of verschillende standaardschema's ( u maakt mogelijk verbinding met de testserver als een andere Windows- of SQL-verificatielogin, bijvoorbeeld). Ik heb veel over deze dingen gesproken in mijn vorige post.
Conclusie
Hoewel er manieren zijn om enkele verschillen te verkleinen (bekijk DBCC OPTIMIZER_WHATIF om uw testserver voor de gek te houden door fenomenale dingen over de onderliggende hardware te geloven), de waarheid is dat het een hele uitdaging zal zijn om twee servers betrouwbaar en consistent identiek te laten presteren, en dat er mogelijk tientallen redenen zijn waarom u verschillende abonnementen of verschillende prestaties kunt krijgen op twee vergelijkbare (of zelfs identieke) servers.
Heb je bepaalde trucs? Heb je ondraaglijke pijnpunten met de bovenstaande ideeën (of andere die ik vergat te vermelden)? Deel het alsjeblieft in de reacties hieronder!