Jag skrev kort om JetShowPlan i min artikel om Tuning Access Query Performance. Som jag skrev i den artikeln är SQL ett deklarativt språk. När du skriver en fråga talar du om för databasmotorn vad du vill. Databasmotorn bestämmer hur bäst att åstadkomma det åt dig. Detta är generellt sett bra, eftersom det är svårt att optimera set-baserade operationer och att låta databasmotorn göra det åt dig gör att du kan utnyttja kunskapen hos dem som ägnar sina liv åt det specifika problemet.
Nackdelen är att hur blir en svart låda. Du matar in lite SQL i den svarta lådan och ut kommer en resultatuppsättning med en massa data. Databasmotorn är extremt tillförlitlig när det gäller att förse dig med exakt den information du efterfrågade. Problemet är att prestandan för datahämtning kan vara överallt. För att vara tydlig är den dåliga prestandan nästan aldrig databasmotorns fel. Vanligtvis är problemet att vi saknar ett index eller filtrering på resultatet av en VBA-funktion eller sammanfogning på två länkade tabeller som är lagrade på fysiskt separata platser.
När detta problem uppstår behöver vi ett sätt att felsöka det. Gå in i JetShowPlan. Se det här som en speciell skruvmejsel som låter oss ta isär den svarta lådan och titta inuti för att se hur databasmotorn implementerar SQL-kommandona vi matar den. Med denna kunskap kan vi justera SQL, lägga till ett index eller på annat sätt ta itu med källan till vår prestandaflaskhals.
Låt oss komma igång.
Registernyckel
JetShowPlan fungerar genom att skriva frågeplanen (d.v.s. innehållet i den svarta rutan) till en textfil närhelst ACE/Jet-databasmotorn kör någon fråga. Den här textfilen fylls snabbt. Att skapa textfilen kräver resurser som ytterligare försämrar frågeprestanda. Därför vill vi bara aktivera den här funktionen när vi aktivt felsöker ett problem.
Eftersom detta är ett verktyg för avancerade användare finns det ingen inställning i Access-användargränssnittet för att aktivera detta läge. Det enda sättet att slå på eller av det är genom att ställa in ett värde i registret. Registervärdet passar följande mönster (texten inuti hängslen fungerar som en platshållare):
[HKEY_LOCAL_MACHINE\SOFTWARE{\Wow6432Node}\Microsoft\Office\{xx}.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"
Version och bitnessöverväganden
Registervärdesmönstret jag visade ovan använder viss platshållartext för att ta hänsyn till skillnaderna mellan Access-miljöer. Versionsnummertexten \{xx}.0\
ska ersättas med versionsnumret som motsvarar versionen av Access installerad på din maskin:
12.0
:Access 200713.0
:hoppade över för att undvika triskaidekafober14.0
:Access 201015.0
:Access 201316.0
:Åtkomst 2016 och 2019
\Wow6432Node
('Wow' står för "Windows 32-bitars på Windows 64-bitars") krävs endast om du kör en 32-bitarsversion av Microsoft Access på en 64-bitarsversion av Windows. Om Access och Windows båda är 32-bitars eller båda 64-bitars, är den "mappen" (eller "nyckeln" i registerjargongen) onödig.
I VBA-form:
If Is32BitAccess Xor Is32BitWindows Then
IncludeWow6432Key = True
Else
IncludeWow6432Key = False
End If
Till exempel skulle en 32-bitarsinstallation av Access 2010 som körs på 64-bitars Windows kräva följande registerpost:
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"
På samma sätt skulle en 64-bitarsinstallation av Access 2019 på 64-bitars Windows kräva:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"
Jag bör också notera att första gången du skapar den här posten kommer du sannolikt att behöva lägga till "Debug"-nyckeln (mapp) och JETSHOWPLAN-värdets namn och data.
Här är stegen för att göra detta:
- Kör regedit som administratör
- Navigera till "\Engines"-tangenten efter ovanstående anteckningar
- Högerklicka på "\Engines" och välj Ny -> Nyckel
- Byt namn på nyckeln från "Ny nyckel #1" till "Debug"
Sedan måste du lägga till "JETSHOWPLAN"-strängvärdet med data "ON " för att möjliggöra tillägg till showplan.out fil eller "AV " för att sluta lägga till filen.
- Högerklicka på "\Debug"-tangenten och välj Nytt -> Strängvärde
- Byt namn på värdet från "Nytt värde #1" till "JETSHOWPLAN"
- Högerklicka på värdenamnet "JETSHOWPLAN" och välj Ändra...
- Ställ in värdedata på PÅ klicka sedan på knappen [OK]
Nästa gång du startar en ny instans av Access kommer den att börja lägga till data till filen Showplan.out. Eventuella instanser av Access som redan körs när du gör ändringarna ovan kommer inte att påverkas. Detsamma gäller när du stänger av inställningen AV . Ändringarna träder inte i kraft förrän du startar en ny msaccess.exe exempel. Det är inte nödvändigt att stänga befintliga instanser av Access; det är möjligt att ha en öppen instans av Access som aktivt skriver till showplan.out medan en annan instans av Access inte är det.
Autohotkey-skript
Jag tänker inte ljuga; hoppa in i regedit varje gång jag vill slå PÅ eller AV JetShowPlan är irriterande. Om jag var tvungen att göra det skulle jag knappt bry mig. Men det behöver jag inte göra! Jag skapade en snabbtangent i Autohotkey som växlar PÅ och AV JetShowPlan.
^#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
Nu när jag vill ställa in mina frågor, trycker jag på [CTl] + [Win] + [Q] och jag ser en meddelanderuta som säger "JetShowPlan inställd på PÅ". När jag är klar stänger jag Access, trycker på [Ctl] + [Win] + [Q] och jag ser "JetShowPlan inställd på AV".
Justera behörigheter
Jag har två olika Windows-användarkonton:ett med standardbehörigheter som jag använder för det dagliga arbetet och ett annat med administratörsbehörigheter för att installera programvara etc. Detta är en vanlig bästa praxis för säkerhet.
Problemet är att JetShowPlan-registernyckeln finns i HKLM-kuben. Som standard kan endast administratörer göra ändringar i värdena i den hive. Detta är irriterande eftersom när jag försöker köra mitt Autohotkey-skript får jag följande felmeddelande:
Oroa dig inte. Som meddelandet ovan antyder kan vi fixa detta. Det bästa är att vi kan göra det bekvämt utan att minska vår säkerhetsställning. Här är tricket.
- Öppna regedit som administratör
- Navigera till \Debug nyckel
- Högerklicka på \Debug och välj Behörigheter...
- Klicka på knappen [Lägg till...]
- Ange användarnamnet från meddelanderutan ovan ('Mike'), klicka på [Kontrollera namn] och klicka sedan på [OK]
- Tillåt [√] "Full kontroll" för användaren
- Klicka på [OK] för att spara ändringarna
När jag nu trycker på [Ctl] + [Win] + [Q] växlar den JetShowPlan PÅ och AV, vilket uppdaterar registret automatiskt.
Hitta Showplan.out
Access kommer inte att varna dig om var Jet/ACE-databasmotorn lägger till frågeplansinformation när JetShowPlan är aktiverat. Jag har tillbringat mer tid än jag bryr mig om att erkänna att leta efter en oseriös kopia av showplan.out . Det här avsnittet kommer att rädda dig från att dela det ödet.
Standardplats
Det första stället att leta är i den aktuella användarens dokumentmapp. Mitt Windows-användarnamn är till exempel "Mike", så det första jag skulle förvänta mig att hitta filen är:C:\Users\Mike\Documents\showplan.out
.
Använda CurDir()
Tekniskt sett är showplan.out filen skapas i den aktuella arbetskatalogen. Det är vanligtvis den aktuella användarens dokumentmapp, men inte alltid. Det idiotsäkra sättet att hitta filens plats är att använda CurDir() funktion.
Du kan kopiera, klistra in och köra följande kodrad i VBA IDE omedelbara fönster för att öppna filen showplan.out (förutsatt att du har aktiverat JetShowPlan i registret):
Shell "notepad """ & CurDir & "\showplan.out""", vbNormalFocus
Ändra utdataplatsen via ChDir()
Om du av någon anledning ville ange en annan plats för showplan.out fil, kan du göra det med ChDir()-funktionen. Den funktionen ändrar den aktuella arbetskatalogen. Och, som jag nämnde tidigare, är den nuvarande katalogen där showplan.out finns filen finns. Så snart du ändrar den aktuella arbetskatalogen, börjar JetShowPlan skriva till den nya mappen; det finns inget behov av att stänga och öppna Access igen.
Varför kanske du vill göra det här? Låt oss säga att du ville jämföra tre olika metoder för att hämta samma data. Du skriver tre olika frågor för att se hur ändringarna du gör påverkar frågeplanen. Sedan showplan.out är så omfattande att det skulle vara trevligt att ha varje frågeplan i sin egen fil. Detta kommer att göra frågeplanerna lättare att jämföra. Så här kunde jag göra det. Det första steget är att se till att var och en av dessa mappar finns. Kör sedan följande kodrader:
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"
Använd allt du har (eller ladda ner det om du inte har det inte än)
Medan CurDir() ger dig en definitiv plats för de senaste ändringarna av showplan.out fil kan den inte berätta vad de tidigare arbetskatalogerna var. Och om du har stängt instansen av Access som skapade showplan.out fil, det finns ingen garanti för att nästa instans av Access som du öppnar kommer att ha samma aktuella katalog.
Jag kom nyligen över ett praktiskt litet verktyg som heter "Allt". Det är en liten körbar fil som indexerar hela din hårddisk på bara några sekunder. När indexeringen är klar kan du omedelbart söka efter filer eller mappar var som helst på din enhet.
Du kan ladda ner Allt härifrån eller via Chocolatey:choco install everything
. Öppna Allt , sök efter showplan.out
, och på mindre än en sekund kommer du att se varje instans av showplan.out på din dator tillsammans med det senaste ändringsdatumet. Jag önskar att jag hade det här verktyget för flera år sedan.
Förstå Showplan.out
Första gången du öppnar en showplan.out fil, förvänta dig att bli förbryllad. Det är mycket text och mycket av det är brus. Här är ett utdrag från en fil som skapades när jag öppnade Northwind-exempeldatabasen:
Frågorna som börjar med en tilde (~
) representerar rå SQL som sparas i egenskapsbladet för ett formulär eller rapport och inte sparas som ett permanent QueryDef-objekt. De viktigaste punkterna av intresse är de numrerade stegen för varje fråga:01)
, 02)
, 03)
Du vill följa dessa steg och leta efter goda tecken och dåliga tecken som kan antyda var det finns problem.
Såvitt jag vet finns det ingen officiell dokumentation för formateringen och innehållet i showplan.out fil. Det är dock OK, eftersom vi inte kommer att fastna i detaljerna. Vårt främsta mål är att identifiera uppenbara problem och ta itu med dem. Här gäller 80/20-regeln. De flesta av prestandavinsterna kommer från en eller två enkla justeringar av våra frågor.
Goda tecken
Det här handlar om index. Vi vill att frågeplanen ska använda index, särskilt i början av en flerstegsfråga. Två olika nyckelord indikerar att index används:index
och rushmore
. Rushmore är kodnamnet för frågeoptimeringsteknologin som ursprungligen utvecklades av Fox Software i början av 1980-talet. Microsoft köpte företaget 1992 och införlivade tekniken i Jet-databasmotorn.
Frågor som använder Rushmore-teknik för att bearbeta index körs snabbare än de som använder index på ett mer traditionellt sätt. Rushmore-tekniken kan endast användas med Access-tabeller (både lokala och länkade), tillsammans med länkade FoxPro- och dBASE-tabeller. Speciellt kan Rushmore inte användas med länkade SQL Server-tabeller. För att höja prestandan för länkade SQL Server-tabeller är det ofta bättre för dig att skriva genomkopplingsfrågor, men det ligger utanför den här artikeln.
Dåliga tecken
Det finns några dåliga tecken att se efter i showplan.out fil. Den enkla närvaron av dessa tecken betyder inte nödvändigtvis att det finns ett problem. Som sagt, om du felsöker en fråga med dålig prestanda kan du tänka på dessa ord som varningsflaggor för potentiella problem:X-Prod
, scanning
, temp
, temporary
.
X-Prod nyckelord visas när du har en fråga med en kartesisk koppling (även känd som en korskoppling eller korsprodukt). Detta händer vanligtvis av misstag när du glömmer att slå samman två tabeller i Query-by-Example (QBE)-redigeraren. Resultatet är att varje post i tabell 1 matchas med varje post i tabell 2. Det totala antalet poster är produkten av de två tabellräkningarna. Så om tabell 1 har 7 poster och tabell 2 har 9 poster, returnerar korskopplingen av de två tabellerna 63 poster. Du kan föreställa dig problemet om båda tabellerna har tusentals poster eller fler.
01) Inner Join table 'Table1' to table 'Table2'
using X-Prod join
Nästa nyckelord att titta efter är skanning . Om databasmotorn inte kan använda ett index för att filtrera resultat faller den tillbaka på skanning. Detta innebär att den måste undersöka varje rad individuellt för att se om den uppfyller frågekriterierna. När du ser detta ord i en showplan.out fil, betyder det ofta att du behöver lägga till ett index i kolumnen som ska skannas. Men inte alltid! För kolumner med låg kardinalitet (bara ett fåtal unika värden, till exempel en statuskolumn), är det vanligtvis inte så bra att lägga till ett index. När det väl har lagts till måste indexet bibehållas. Detta saktar ner insättningar och tar upp diskutrymme. Dessutom, om frågeprestanda är acceptabel för produktionsdata, är det en för tidig optimering att lägga till ett index i den skannade kolumnen (vilket du bör undvika).
Slutligen finns det temp och tillfälligt nyckelord. Dessa indikerar att databasmotorn har varit tvungen att utföra någon form av operation på tillfällig basis. När vi skapar och sparar en querydef, sparas det objektet med viss metadata för att optimera upprepad exekvering. Uppenbarligen går sådan metadata förlorad när temporära index eller kopplingar går utom räckvidden. Dessa sökord kan vanligtvis ignoreras, men de kanske kan peka dig i rätt riktning om du råkar ut för en fråga som ger dåligt resultat utan andra mer uppenbara brister.
För att sammanfatta i alltför förenklade termer:
BRA > > > > > DÅLIG:
Rushmore> index> temp/temporary> scanning> X-Prod
Anteckningsblock++ anpassat språk
Om du har läst mitt andra arbete, vet du att jag har starka känslor för att öka signal-brusförhållandet i programmering (och livet i allmänhet). För detta ändamål skapade jag en "Användardefinierat språk"-fil i Notepad++ för att lägga till syntaxmarkering i showplan.out filer. Nu, när jag öppnar showplan.out filer ser de ut som skärmdumpen nedan. Nyckelorden "BRA" är färgade i blå text och nyckelorden "BAD" är färgade i röd text. Det här är ett exempel på att få fel kod att se fel ut.
Följ dessa steg för att ställa in detta:
- Öppna Notepad++
- Språk -> Användardefinierat språk -> Definiera ditt språk...
- Klicka på [Skapa ny...]
- Ange namn:showplan.out
- Klicka på [OK]
- Gå till _| Mapp och standard|_fliken
- Under "Vikning i kod 2-stil" anger du
Inputs
för Open ochEnd inputs
för Stäng - Gå till fliken _|Sökordslista|_
- Klicka på [Styler] under den första gruppen och ställ in förgrundsfärgen på röd
- Ange följande "BAD"-sökord i den första gruppen:
temp temporary scanning X-Prod
- Klicka på [Styler] under den andra gruppen och ställ in förgrundsfärgen på blå
- Ange följande "BRA" sökord i den andra gruppen:
rushmore index
- Enter Ext.:out
Sluta tankar
Till skillnad från SQL Server tillåter inte Jet/ACE-databasmotorn dig att direkt modifiera exekveringsplaner för frågor. Det betyder att vi kan titta in i den svarta lådan med JetShowPlan, men vi kan inte koppla om den för att göra vad vi vill. Istället måste vi fokusera på vad vi kan kontrollera:den exakta SQL vi matar den och indexen och relationerna mellan de inblandade tabellerna.
Att använda JetShowPlan har både kort- och långsiktiga fördelar. På kort sikt låter funktionen dig fixa flaskhalsarna i dina Access-applikationer. På lång sikt får du insikt i Accesss inre funktioner, vilket hjälper dig att undvika flaskhalsarna i första hand.