Jeg skrev kort om JetShowPlan i min artikel om Tuning Access Query Performance. Som jeg skrev i den artikel, er SQL et deklarativt sprog. Når du skriver en forespørgsel, fortæller du databasemotoren hvad du vil have. Databasemotoren bestemmer hvordan bedst at opnå det for dig. Dette er generelt godt, fordi det er svært at optimere sæt-baserede operationer, og at lade databasemotoren gøre det for dig giver dig mulighed for at udnytte viden hos dem, der vier deres liv til det specifikke problem.
Ulempen er, at hvordan bliver en sort boks. Du fodrer noget SQL ind i den sorte boks, og der kommer et resultatsæt med en masse data. Databasemotoren er ekstremt pålidelig til at give dig præcis de data, du har anmodet om. Problemet er, at ydelsen af datahentningen kan være overalt. For at være klar, er den dårlige ydeevne næsten aldrig databasemotorens skyld. Normalt er problemet, at vi mangler et indeks eller filtrering på resultatet af en VBA-funktion eller sammenføjning på to sammenkædede tabeller, der er gemt fysisk adskilte steder.
Når dette problem opstår, har vi brug for en måde at fejlfinde det på. Gå ind i JetShowPlan. Tænk på dette som en speciel skruetrækker, der giver os mulighed for at skille den sorte boks ad og kigge ind for at se hvordan databasemotoren implementerer de SQL-kommandoer, vi fodrer den med. Med denne viden kan vi justere SQL'en, tilføje et indeks eller på anden måde adressere kilden til vores ydeevneflaskehals.
Lad os komme i gang.
Registry Key
JetShowPlan fungerer ved at skrive forespørgselsplanen (dvs. indholdet af den sorte boks) til en tekstfil, når ACE/Jet-databasemotoren udfører enhver forespørgsel. Denne tekstfil fyldes hurtigt op. Oprettelse af tekstfilen kræver ressourcer, der yderligere forringer forespørgselsydeevnen. Derfor ønsker vi kun at aktivere denne funktion, når vi aktivt fejlfinder et problem.
Da dette er et værktøj for avancerede brugere, er der ingen indstilling i Access-brugergrænsefladen til at aktivere denne tilstand. Den eneste måde at slå det til eller fra er ved at indstille en værdi i registreringsdatabasen. Registreringsværdien passer til følgende mønster (teksten inden i krøllede seler fungerer som en pladsholder):
[HKEY_LOCAL_MACHINE\SOFTWARE{\Wow6432Node}\Microsoft\Office\{xx}.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"
Version og bitness-overvejelser
Registreringsværdimønsteret, jeg viste ovenfor, bruger noget pladsholdertekst til at tage højde for forskellene mellem Access-miljøer. Versionsnummerteksten \{xx}.0\
skal erstattes med det versionsnummer, der svarer til den version af Access, der er installeret på din maskine:
12.0
:Access 200713.0
:sprunget over for at undgå at udløse triskaidekafober14.0
:Access 201015.0
:Access 201316.0
:Adgang 2016 &2019
\Wow6432Node
('Wow' står for "Windows 32-bit på Windows 64-bit") er kun påkrævet, hvis du kører en 32-bit version af Microsoft Access på en 64-bit version af Windows. Hvis Access og Windows begge er 32-bit eller begge 64-bit, så er den "mappe" (eller "nøgle" i registreringsdatabasen) unødvendig.
I VBA-form:
If Is32BitAccess Xor Is32BitWindows Then
IncludeWow6432Key = True
Else
IncludeWow6432Key = False
End If
For eksempel vil en 32-bit installation af Access 2010, der kører på 64-bit Windows, kræve følgende post i registreringsdatabasen:
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"
Ligeledes ville en 64-bit installation af Access 2019 på 64-bit Windows kræve:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"
Jeg skal også bemærke, at første gang du opretter denne post, skal du sandsynligvis tilføje "Debug"-nøglen (mappe) og JETSHOWPLAN-værdiens navn og data.
Her er trinene til at gøre dette:
- Kør regedit som administrator
- Naviger til "\Engines"-tasten efter ovenstående bemærkninger
- Højreklik på "\Engines", og vælg Ny -> Nøgle
- Omdøb nøglen fra "Ny nøgle #1" til "Debug"
Derefter skal du tilføje "JETSHOWPLAN"-strengværdien med data "ON " for at aktivere tilføjelse til showplan.out fil eller "OFF " for at stoppe med at tilføje til filen.
- Højreklik på "\Debug"-tasten og vælg Ny -> Strengværdi
- Omdøb værdien fra "Ny værdi #1" til "JETSHOWPLAN"
- Højreklik på "JETSHOWPLAN"-værdinavnet, og vælg Rediger...
- Sæt værdidataene til TIL klik derefter på knappen [OK]
Næste gang du starter en ny instans af Access, begynder den at tilføje data til filen Showplan.out. Eventuelle forekomster af Access, der allerede kører, når du foretager ovenstående ændringer, vil ikke blive påvirket. Det samme gælder, når du slår indstillingen OFF . Ændringerne træder ikke i kraft, før du starter en ny msaccess.exe eksempel. Det er ikke nødvendigt at lukke eksisterende forekomster af Access; det er muligt at have én åben instans af Access, der aktivt skriver til showplan.out, mens en anden instans af Access ikke er det.
Autohotkey-script
Jeg skal ikke lyve; hopper ind i regedit hver gang jeg vil slå JetShowPlan TIL eller FRA er irriterende. Hvis jeg skulle gøre det, ville jeg næsten ikke gide det. Men det behøver jeg ikke gøre! Jeg oprettede en genvejstast i Autohotkey, der slår JetShowPlan TIL og FRA.
^#q:: ; Ctl + Win + Q (feel free to use your own key combination)
;--== Toggle JETSHOWPLAN ==--
;----- BEGIN CONFIGURATION (make all changes here) -------------
ShowPlanRegView = 64 ; set to 32 for 32-bit Access
ShowPlanKey = SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engine\Engines\Debug ; change 16.0 to match Access version
;----- END CONFIGURATION ---------------------------------------
SetRegView %ShowPlanRegView%
RegRead ShowPlanSetting, HKEY_LOCAL_MACHINE\%ShowPlanKey%, JETSHOWPLAN
If ( ShowPlanSetting = "OFF" ) {
RegWrite REG_SZ, HKEY_LOCAL_MACHINE\%ShowPlanKey%, JETSHOWPLAN, ON
If ErrorLevel
MsgBox Error enabling JetShowPlan. Check permissions on:`n`nHKLM\%ShowPlanKey%`n`nfor user '%A_UserName%'
Else
MsgBox JetShowPlan set to ON
} Else {
RegWrite REG_SZ, HKEY_LOCAL_MACHINE\%ShowPlanKey%, JETSHOWPLAN, OFF
If ErrorLevel
MsgBox Error disabling JetShowPlan. Check permissions on:`n`nHKLM\%ShowPlanKey%`n`nfor user '%A_UserName%'
Else
MsgBox JetShowPlan set to OFF
}
SetRegView Default
Return
Når jeg nu vil justere mine forespørgsler, trykker jeg på [Ctl] + [Win] + [Q], og jeg ser en beskedboks, der siger "JetShowPlan sat til ON". Når jeg er færdig, lukker jeg Access, trykker på [Ctl] + [Win] + [Q] og jeg ser "JetShowPlan sat til OFF".
Justering af tilladelser
Jeg har to forskellige Windows-brugerkonti:En med standardtilladelser, som jeg bruger til det daglige arbejde, og en anden med administratortilladelser til installation af software osv. Dette er en almindelig bedste praksis for sikkerhed.
Problemet er, at JetShowPlan-registreringsnøglen er i HKLM-bikuben. Som standard er det kun administratorer, der kan foretage ændringer i værdierne i det pågældende hive. Dette er irriterende, fordi når jeg prøver at køre mit Autohotkey-script, får jeg følgende fejlmeddelelse:
Du skal dog ikke bekymre dig. Som meddelelsen ovenfor antyder, kan vi ordne dette. Det bedste er, at vi kan gøre det praktisk uden at reducere vores sikkerhedsstilling. Her er tricket.
- Åbn regedit som administrator
- Naviger til \Debug nøgle
- Højreklik på \Debug tast og vælg Tilladelser...
- Klik på knappen [Tilføj...]
- Indtast brugernavnet fra meddelelsesboksen ovenfor ('Mike'), klik på [Check Names], og klik derefter på [OK]
- Tillad [√] "Fuld kontrol" for brugeren
- Klik på [OK] for at gemme ændringerne
Når jeg nu trykker på [Ctl] + [Win] + [Q], skifter det JetShowPlan TIL og FRA, hvilket opdaterer registreringsdatabasen automatisk.
Find Showplan.out
Access vil ikke advare dig om, hvor Jet/ACE-databasemotoren tilføjer oplysninger om forespørgselsplan, når JetShowPlan er aktiveret. Jeg har brugt mere tid end jeg gider på at indrømme på at søge efter en useriøs kopi af showplan.out . Denne sektion vil redde dig fra at dele den skæbne.
Standardplacering
Det første sted at kigge er i den aktuelle brugers Dokumenter-mappe. For eksempel er mit Windows-brugernavn "Mike", så det første sted jeg ville forvente at finde filen er:C:\Users\Mike\Documents\showplan.out
.
Brug af CurDir()
Teknisk set er showplan.out filen oprettes i den aktuelle arbejdsmappe. Det er normalt den aktuelle brugers Dokumenter-mappe, men ikke altid. Den idiotsikre måde at finde filens placering på er at bruge CurDir() funktion.
Du kan kopiere, indsætte og udføre følgende kodelinje i VBA IDE-vinduet for at åbne filen showplan.out (forudsat at du har aktiveret JetShowPlan i registreringsdatabasen):
Shell "notepad """ & CurDir & "\showplan.out""", vbNormalFocus
Ændring af outputplacering via ChDir()
Hvis du af en eller anden grund ønskede at angive en anden placering for showplan.out fil, kan du gøre det ved at bruge ChDir()-funktionen. Denne funktion ændrer den aktuelle arbejdsmappe. Og som jeg nævnte tidligere, er den aktuelle mappe, hvor showplan.out filen ligger. Så snart du ændrer den aktuelle arbejdsmappe, begynder JetShowPlan at skrive til den nye mappe; der er ingen grund til at lukke og genåbne Access.
Hvorfor vil du måske gøre dette? Lad os sige, at du ville sammenligne tre forskellige tilgange til at hente de samme data. Du skriver tre forskellige forespørgsler for at se, hvordan de ændringer, du foretager, påvirker forespørgselsplanen. Siden showplan.out er så omfattende, at det ville være rart at have hver forespørgselsplan i sin egen fil. Dette vil gøre forespørgselsplanerne nemmere at sammenligne. Her er hvordan jeg kunne gøre det. Det første trin er at sikre, at hver af disse mapper eksisterer. Udfør derefter følgende kodelinjer:
ChDir "C:\Users\Mike\Documents\Showplan\A"
DoCmd.OpenQuery "CollectTax1"
ChDir "C:\Users\Mike\Documents\Showplan\B"
DoCmd.OpenQuery "CollectTax2"
ChDir "C:\Users\Mike\Documents\Showplan\C"
DoCmd.OpenQuery "CollectTax3"
ChDir "C:\Users\Mike\Documents"
Brug alt hvad du har (eller download det, hvis du ikke har det ikke endnu)
Mens CurDir() vil give dig en endelig placering for de seneste ændringer af showplan.out fil, kan den ikke fortælle dig, hvad de tidligere arbejdsmapper var. Og hvis du har lukket den forekomst af Access, der skabte showplan.out fil, er der ingen garanti for, at den næste forekomst af Access, du åbner, vil have den samme aktuelle mappe.
Jeg stødte for nylig på et praktisk lille hjælpeprogram kaldet "Alt." Det er en lille eksekverbar fil, der indekserer hele din harddisk på få sekunder. Når indekseringen er fuldført, kan du øjeblikkeligt søge efter filer eller mapper hvor som helst på dit drev.
Du kan downloade Alt herfra eller via Chocolatey:choco install everything
. Åbn Alt , søg efter showplan.out
, og på mindre end et sekund vil du se alle forekomster af showplan.out på din computer sammen med den sidste ændringsdato. Jeg ville ønske, jeg havde dette værktøj for mange år siden.
Få mening med Showplan.out
Første gang du åbner en showplan.out fil, forventer at blive forvirret. Der er meget tekst, og meget af det er støj. Her er et uddrag fra en fil, der blev genereret, da jeg åbnede Northwind-eksempeldatabasen:
Forespørgslerne, der begynder med en tilde (~
) repræsenterer rå SQL, der er gemt i egenskabsarket for en formular eller rapport og ikke gemt som et permanent QueryDef-objekt. De vigtigste interessepunkter er de nummererede trin for hver forespørgsel:01)
, 02)
, 03)
osv. Du vil følge disse trin på udkig efter gode tegn og dårlige tegn, der kan tyde på, hvor der er problemer.
Så vidt jeg ved, er der ingen officiel dokumentation for formateringen og indholdet af showplan.out fil. Det er dog okay, for vi kommer ikke til at blive fanget af detaljerne. Vores hovedmål er at identificere åbenlyse problemer og løse dem. Her gælder 80/20-reglen. De fleste af præstationsgevinsterne kommer fra en eller to simple justeringer af vores forespørgsler.
Gode tegn
Det hele handler om indekser. Vi ønsker, at forespørgselsplanen skal bruge indekser, især i begyndelsen af en forespørgsel med flere trin. To forskellige nøgleord indikerer, at indekser bliver brugt:index
og rushmore
. Rushmore er kodenavnet for forespørgselsoptimeringsteknologien, der oprindeligt blev udviklet af Fox Software i begyndelsen af 1980'erne. Microsoft købte virksomheden i 1992 og inkorporerede teknologien i Jet-databasemotoren.
Forespørgsler, der bruger Rushmore-teknologi til at behandle indekser, kører hurtigere end dem, der bruger indekser på en mere traditionel måde. Rushmore-teknologi kan kun bruges med Access-tabeller (både lokale og sammenkædede), sammen med sammenkædede FoxPro- og dBASE-tabeller. Navnlig kan Rushmore ikke bruges med sammenkædede SQL Server-tabeller. For at øge ydeevnen af linkede SQL Server-tabeller er du ofte bedre stillet til at skrive pass-through-forespørgsler, men det er uden for denne artikels omfang.
Dårlige tegn
Der er et par dårlige tegn at holde øje med i showplan.out fil. Den simple tilstedeværelse af disse tegn betyder ikke nødvendigvis, at der er et problem. Når det er sagt, hvis du fejlfinder en forespørgsel med dårlig ydeevne, kan du tænke på disse ord som advarselsflag for potentielle problemer:X-Prod
, scanning
, temp
, temporary
.
X-Prod søgeord vises, når du har en forespørgsel med en kartesisk joinforbindelse (også kendt som en krydssammenføjning eller krydsprodukt). Dette sker normalt ved en fejl, når du glemmer at forbinde to tabeller i Query-by-Example (QBE)-editoren. Resultatet er, at hver post i tabel 1 bliver matchet med hver post i tabel 2. Det samlede antal poster er produktet af de to tabeloptællinger. Så hvis tabel 1 har 7 poster, og tabel 2 har 9 poster, returnerer krydsforbindelsen af de to tabeller 63 poster. Du kan forestille dig problemet, hvis begge tabeller har tusindvis af poster eller mere.
01) Inner Join table 'Table1' to table 'Table2'
using X-Prod join
Det næste søgeord, du skal holde øje med, er scanning . Hvis databasemotoren ikke kan bruge et indeks til at filtrere resultater, falder den tilbage på scanning. Det betyder, at den skal undersøge hver række individuelt for at se, om den opfylder forespørgselskriterierne. Når du ser dette ord i en showplan.out fil, betyder det ofte, at du skal tilføje et indeks til den kolonne, der scannes. Men ikke altid! For kolonner med lav kardinalitet (kun nogle få unikke værdier, f.eks. en statuskolonne), er der normalt lidt fordel ved at tilføje et indeks. Når det er tilføjet, skal indekset vedligeholdes. Dette forsinker indsættelser og optager diskplads. Hvis forespørgselsydeevnen er acceptabel på produktionsdata, er tilføjelse af et indeks til den scannede kolonne en for tidlig optimering (som du bør undgå).
Endelig er der temp og midlertidig søgeord. Disse indikerer, at databasemotoren har været nødt til at udføre en eller anden form for operation på midlertidig basis. Når vi opretter og gemmer en querydef, gemmes det objekt med visse metadata for at optimere gentagen eksekvering. Naturligvis går sådanne metadata tabt, når midlertidige indekser eller sammenføjninger går uden for rækkevidde. Disse søgeord kan normalt ignoreres, men de kan muligvis pege dig i den rigtige retning, hvis du bliver stødt på en dårligt effektiv forespørgsel uden andre mere åbenlyse fejl.
For at opsummere i alt for forenklede vendinger:
GOD > > > > > DÅRLIG:
Rushmore> indekser> midlertidig/midlertidig> scanning> X-Prod
Notepad++ brugerdefineret sprog
Hvis du har læst mit andet arbejde, ved du, at jeg har stærke følelser omkring at øge signal-støj-forholdet i programmering (og livet generelt). Til dette formål oprettede jeg en "Brugerdefineret sprog"-fil i Notepad++ for at tilføje syntaksfremhævning til showplan.out filer. Nu, når jeg åbner showplan.out filer, ser de ud som skærmbilledet nedenfor. Nøgleordene "GOD" er farvet med blå tekst, og nøgleordene "DÅRLIG" er farvet med rød tekst. Dette er et eksempel på at få forkert kode til at se forkert ud.
Følg disse trin for at konfigurere dette:
- Åbn Notepad++
- Sprog -> Brugerdefineret sprog -> Definer dit sprog...
- Klik på [Opret ny...]
- Indtast navn:showplan.out
- Klik på [OK]
- Gå til _| Mappe og standard|_ fanen
- Under "Foldning i kode 2-stil" skal du indtaste
Inputs
for Open ogEnd inputs
for Luk - Gå til fanen _|Søgeordsliste|_
- Klik på [Styler] under 1. gruppe, og indstil forgrundsfarven til rød
- Indtast følgende "DÅRLIGE" søgeord i 1. gruppe:
temp temporary scanning X-Prod
- Klik på [Styler] under 2. gruppe, og indstil forgrundsfarven til blå
- Indtast følgende "GODE" søgeord i 2. gruppe:
rushmore index
- Enter Ext.:out
Sidste tanker
I modsætning til SQL Server tillader Jet/ACE-databasemotoren dig ikke direkte at ændre forespørgselsudførelsesplaner. Det betyder, at vi kan se ind i den sorte boks med JetShowPlan, men vi kan ikke omkoble den til at gøre, hvad vi vil. I stedet er vi nødt til at fokusere på det, vi kan kontrollere:den nøjagtige SQL, vi tilfører den, og indekserne og relationerne mellem de involverede tabeller.
Brug af JetShowPlan har både kort- og langsigtede fordele. På kort sigt lader funktionen dig løse flaskehalsene i dine Access-applikationer. På lang sigt får du indsigt i Access, som hjælper dig med at undgå flaskehalsene i første omgang.