Access
 sql >> Datenbank >  >> RDS >> Access

JetShowPlan:Eine Einführung

Ich habe in meinem Artikel über die Optimierung der Zugriffsabfrageleistung kurz über JetShowPlan geschrieben. Wie ich in diesem Artikel geschrieben habe, ist SQL eine deklarative Sprache. Wenn Sie eine Abfrage schreiben, teilen Sie der Datenbank-Engine was mit Sie wollen. Die Datenbank-Engine entscheidet wie das erledige ich am besten für dich. Dies ist im Allgemeinen gut, da die Optimierung satzbasierter Operationen schwierig ist und die Datenbank-Engine dies für Sie erledigen lässt, ermöglicht es Ihnen, das Wissen derer zu nutzen, die ihr Leben diesem spezifischen Problem widmen.

Der Nachteil ist, dass das wie wird zur Blackbox. Sie füttern etwas SQL in die Blackbox und heraus kommt eine Ergebnismenge mit einer Reihe von Daten. Die Datenbank-Engine liefert Ihnen äußerst zuverlässig genau die Daten, die Sie angefordert haben. Das Problem ist, dass die Leistung des Datenabrufs überall schwanken kann. Um es klar zu sagen, die schlechte Leistung ist fast nie die Schuld der Datenbank-Engine. Normalerweise besteht das Problem darin, dass wir einen Index vermissen oder nach dem Ergebnis einer VBA-Funktion filtern oder zwei verknüpfte Tabellen verbinden, die an physisch getrennten Orten gespeichert sind.

Wenn dieses Problem auftritt, brauchen wir eine Möglichkeit, es zu beheben. Geben Sie JetShowPlan ein. Stellen Sie sich das als einen speziellen Schraubendreher vor, der es uns ermöglicht, die Blackbox auseinanderzunehmen und hineinzuschauen, um wie zu sehen Die Datenbank-Engine implementiert die SQL-Befehle, die wir ihr zuführen. Mit diesem Wissen können wir die SQL optimieren, einen Index hinzufügen oder auf andere Weise die Quelle unseres Leistungsengpasses angehen.

Fangen wir an.

Registrierungsschlüssel

JetShowPlan funktioniert, indem es den Abfrageplan (d. h. den Inhalt der Blackbox) in eine Textdatei schreibt, wenn die ACE/Jet-Datenbank-Engine any ausführt Anfrage. Diese Textdatei füllt sich schnell. Das Erstellen der Textdatei erfordert Ressourcen, die die Abfrageleistung weiter beeinträchtigen. Daher möchten wir diese Funktion nur aktivieren, wenn wir aktiv ein Problem beheben.

Da dies ein Tool für fortgeschrittene Benutzer ist, gibt es keine Einstellung in der Access-Benutzeroberfläche, um diesen Modus zu aktivieren. Die einzige Möglichkeit, es ein- oder auszuschalten, besteht darin, einen Wert in der Registrierung festzulegen. Der Registrierungswert entspricht dem folgenden Muster (der Text in geschweiften Klammern dient als Platzhalter):

[HKEY_LOCAL_MACHINE\SOFTWARE{\Wow6432Node}\Microsoft\Office\{xx}.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"

Überlegungen zu Version und Bitanzahl

Das oben gezeigte Registrierungswertmuster verwendet Platzhaltertext, um die Unterschiede zwischen Access-Umgebungen zu berücksichtigen. Der Text der Versionsnummer \{xx}.0\ sollte durch die Versionsnummer ersetzt werden, die der Version von Access entspricht, die auf Ihrem Computer installiert ist:

  • 12.0 :Access 2007
  • 13.0 :übersprungen, um keine Triskaidekaphobe auszulösen
  • 14.0 :Zugang 2010
  • 15.0 :Zugang 2013
  • 16.0 :Zugriff 2016 &2019

Der \Wow6432Node („Wow“ steht für „Windows 32-Bit auf Windows 64-Bit“) ist nur erforderlich, wenn Sie eine 32-Bit-Version von Microsoft Access auf einer 64-Bit-Version von Windows ausführen. Wenn Access und Windows beide 32-Bit oder beide 64-Bit sind, dann ist dieser "Ordner" (oder "Schlüssel" im Registrierungsjargon) unnötig.

In VBA-Form:

    If Is32BitAccess Xor Is32BitWindows Then
        IncludeWow6432Key = True
    Else
        IncludeWow6432Key = False
    End If

Beispielsweise würde eine 32-Bit-Installation von Access 2010 unter 64-Bit-Windows den folgenden Registrierungseintrag erfordern:

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"

Ebenso würde eine 64-Bit-Installation von Access 2019 auf 64-Bit-Windows Folgendes erfordern:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"

Ich sollte auch beachten, dass Sie beim ersten Erstellen dieses Eintrags wahrscheinlich den "Debug"-Schlüssel (Ordner) und den Namen und die Daten des JETSHOWPLAN-Werts hinzufügen müssen.

Hier sind die Schritte dazu:

  1. Führen Sie regedit aus als Administrator
  2. Navigieren Sie zum Schlüssel "\Engines", indem Sie den obigen Hinweisen folgen
  3. Klicken Sie mit der rechten Maustaste auf "\Engines" und wählen Sie Neu -> Schlüssel
  4. Benennen Sie den Schlüssel von "Neuer Schlüssel #1" in "Debug" um

Dann müssen Sie den Zeichenfolgenwert „JETSHOWPLAN“ mit den Daten „ON hinzufügen ", um das Anhängen an showplan.out zu ermöglichen Datei oder "AUS ", um das Anhängen an die Datei zu beenden.

  1. Klicken Sie mit der rechten Maustaste auf die Taste "\Debug" und wählen Sie Neu -> Zeichenfolgenwert
  2. Benennen Sie den Wert von "Neuer Wert #1" in "JETSHOWPLAN" um
  3. Klicken Sie mit der rechten Maustaste auf den Wertnamen "JETSHOWPLAN" und wählen Sie "Ändern...".
  4. Setzen Sie die Wertdaten auf EIN Klicken Sie dann auf die Schaltfläche [OK]

Wenn Sie das nächste Mal eine neue Instanz von Access starten, werden Daten an die Datei „Showplan.out“ angehängt. Alle Instanzen von Access, die bereits ausgeführt werden, wenn Sie die oben genannten Änderungen vornehmen, sind nicht betroffen. Dasselbe gilt, wenn Sie die Einstellung auf OFF stellen . Die Änderungen werden erst wirksam, wenn Sie eine neue msaccess.exe starten Beispiel. Es ist nicht erforderlich, vorhandene Instanzen von Access zu schließen; Es ist möglich, dass eine offene Instanz von Access aktiv in showplan.out schreibt, während eine andere Instanz von Access dies nicht tut.

Autohotkey-Skript

Ich werde nicht lügen; in regedit springen Jedes Mal, wenn ich JetShowPlan ein- oder ausschalten möchte, ist das ärgerlich. Wenn ich das tun müsste, würde ich mir kaum die Mühe machen. Aber das muss ich nicht! Ich habe in Autohotkey einen Hotkey erstellt, der JetShowPlan ein- und ausschaltet.

^#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

Wenn ich jetzt meine Abfragen optimieren möchte, drücke ich [Strg] + [Win] + [Q] und sehe ein Meldungsfeld mit der Aufschrift „JetShowPlan auf EIN gesetzt“. Wenn ich fertig bin, schließe ich Access, drücke [Strg] + [Win] + [Q] und ich sehe „JetShowPlan auf AUS gesetzt“.

Berechtigungen anpassen

Ich habe zwei verschiedene Windows-Benutzerkonten:eines mit Standardberechtigungen, das ich für die tägliche Arbeit verwende, und ein anderes mit Administratorberechtigungen zum Installieren von Software usw. Dies ist eine gängige Best Practice für die Sicherheit.

Das Problem ist, dass sich der JetShowPlan-Registrierungsschlüssel im HKLM-Hive befindet. Standardmäßig können nur Administratoren Änderungen an den Werten in diesem Hive vornehmen. Das ist ärgerlich, denn wenn ich versuche, mein Autohotkey-Skript auszuführen, erhalte ich die folgende Fehlermeldung:

Aber keine Sorge. Wie die obige Meldung andeutet, können wir dies beheben. Das Beste daran ist, dass wir es bequem machen können, ohne unsere Sicherheitslage zu beeinträchtigen. Hier ist der Trick.

  1. Öffnen Sie regedit als Administrator
  2. Navigieren Sie zu \Debug Schlüssel
  3. Klicken Sie mit der rechten Maustaste auf \Debug -Taste und wählen Sie Berechtigungen...
  4. Klicken Sie auf die Schaltfläche [Hinzufügen...]
  5. Geben Sie den Benutzernamen aus dem Meldungsfeld oben ein ('Mike'), klicken Sie auf [Namen prüfen] und dann auf [OK]
  6. Erlaube [√] "Volle Kontrolle" für den Benutzer
  7. Klicken Sie auf [OK], um die Änderungen zu speichern

Wenn ich jetzt [Strg] + [Win] + [Q] drücke, wird JetShowPlan ein- und ausgeschaltet und die Registrierung automatisch aktualisiert.

Showplan.out finden

Access weist Sie nicht darauf hin, wo das Jet/ACE-Datenbankmodul Abfrageplaninformationen anfügt, wenn JetShowPlan aktiviert ist. Ich habe mehr Zeit damit verbracht, als ich zugeben möchte, nach einer betrügerischen Kopie von showplan.out zu suchen . Dieser Abschnitt wird Sie davor bewahren, dieses Schicksal zu teilen.

Standardstandort

Der erste Ort, an dem Sie nachsehen müssen, ist der Ordner "Dokumente" des aktuellen Benutzers. Zum Beispiel ist mein Windows-Benutzername „Mike“, also würde ich die Datei als erstes erwarten:C:\Users\Mike\Documents\showplan.out .

Mit CurDir()

Technisch gesehen die showplan.out Datei wird im aktuellen Arbeitsverzeichnis erstellt. Das ist normalerweise der Ordner Dokumente des aktuellen Benutzers, aber nicht immer. Der idiotensichere Weg, den Speicherort der Datei zu finden, ist die Verwendung von CurDir() Funktion.

Sie können die folgende Codezeile im Direktfenster der VBA-IDE kopieren, einfügen und ausführen, um die Datei showplan.out zu öffnen (vorausgesetzt, Sie haben JetShowPlan in der Registrierung aktiviert):

Shell "notepad """ & CurDir & "\showplan.out""", vbNormalFocus

Ändern des Ausgabespeicherorts über ChDir()

Falls Sie aus irgendeinem Grund einen anderen Speicherort für showplan.out angeben wollten Datei können Sie dies mit der Funktion ChDir() tun. Diese Funktion ändert das aktuelle Arbeitsverzeichnis. Und wie ich bereits erwähnt habe, befindet sich im aktuellen Verzeichnis die showplan.out Datei liegt. Sobald Sie das aktuelle Arbeitsverzeichnis ändern, beginnt JetShowPlan mit dem Schreiben in den neuen Ordner; Access muss nicht geschlossen und erneut geöffnet werden.

Warum möchten Sie das tun? Angenommen, Sie möchten drei verschiedene Ansätze zum Abrufen derselben Daten vergleichen. Sie schreiben drei verschiedene Abfragen, um zu sehen, wie sich die von Ihnen vorgenommenen Änderungen auf den Abfrageplan auswirken. Seit showplan.out so ausführlich ist, wäre es schön, jeden Abfrageplan in einer eigenen Datei zu haben. Dadurch lassen sich die Abfragepläne leichter vergleichen. Hier ist, wie ich das tun könnte. Der erste Schritt besteht darin, sicherzustellen, dass jeder dieser Ordner vorhanden ist. Führen Sie dann die folgenden Codezeilen aus:

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"

Verwende alles, was du hast (oder lade es herunter, falls du es nicht hast habe es noch nicht)

Während CurDir() Ihnen einen endgültigen Ort für die letzten Änderungen an showplan.out gibt Datei, es kann Ihnen nicht sagen, was die vorherigen Arbeitsverzeichnisse waren. Und wenn Sie die Instanz von Access geschlossen haben, die showplan.out erstellt hat -Datei gibt es keine Garantie dafür, dass die nächste Instanz von Access, die Sie öffnen, dasselbe aktuelle Verzeichnis hat.

Ich bin kürzlich auf ein praktisches kleines Dienstprogramm namens "Everything" gestoßen. Es ist eine winzige ausführbare Datei, die Ihre gesamte Festplatte in nur wenigen Sekunden indiziert. Sobald die Indizierung abgeschlossen ist, können Sie sofort überall auf Ihrem Laufwerk nach Dateien oder Ordnern suchen.

Sie können Alles herunterladen von hier oder über Chocolatey:choco install everything . Öffnen Sie Alles , suchen Sie nach showplan.out , und in weniger als einer Sekunde sehen Sie jede Instanz von showplan.out zusammen mit dem Datum der letzten Änderung auf Ihrem Computer. Ich wünschte, ich hätte dieses Tool schon vor Jahren gehabt.

Showplan.out sinnvoll machen

Beim ersten Öffnen einer showplan.out Datei, rechnen Sie damit, verblüfft zu sein. Es gibt viel Text und vieles davon ist Rauschen. Hier ist ein Auszug aus einer Datei, die generiert wurde, als ich die Northwind-Beispieldatenbank geöffnet habe:

Die Abfragen, die mit einer Tilde beginnen (~ ) stellen unformatiertes SQL dar, das im Eigenschaftenblatt eines Formulars oder Berichts gespeichert und nicht als permanentes QueryDef-Objekt gespeichert wird. Die Hauptinteressenpunkte sind die nummerierten Schritte für jede Abfrage:01) , 02) , 03) usw.  Sie sollten diesen Schritten folgen und nach guten und schlechten Anzeichen suchen, die auf Probleme hindeuten könnten.

Meines Wissens gibt es keine offizielle Dokumentation für die Formatierung und den Inhalt von showplan.out Datei. Das ist aber in Ordnung, weil wir uns nicht in Kleinigkeiten aufhalten werden. Unser Hauptziel ist es, offensichtliche Probleme zu identifizieren und diese anzugehen. Hier gilt die 80/20-Regel. Die meisten Leistungssteigerungen ergeben sich aus ein oder zwei einfachen Anpassungen an unseren Abfragen.

Gute Zeichen

Hier dreht sich alles um Indizes. Wir möchten, dass der Abfrageplan Indizes verwendet, insbesondere in den Anfangsschritten einer mehrstufigen Abfrage. Zwei verschiedene Schlüsselwörter zeigen an, dass Indizes verwendet werden:index und rushmore . Rushmore ist der Codename für die Abfrageoptimierungstechnologie, die ursprünglich Anfang der 1980er Jahre von Fox Software entwickelt wurde. Microsoft kaufte das Unternehmen 1992 und integrierte die Technologie in die Jet-Datenbank-Engine.

Abfragen, die Rushmore-Technologie zum Verarbeiten von Indizes verwenden, werden schneller ausgeführt als Abfragen, die Indizes auf traditionellere Weise verwenden. Die Rushmore-Technologie kann nur mit Access-Tabellen (sowohl lokal als auch verknüpft) zusammen mit verknüpften FoxPro- und dBASE-Tabellen verwendet werden. Insbesondere kann Rushmore nicht mit verknüpften SQL Server-Tabellen verwendet werden. Um die Leistung verknüpfter SQL Server-Tabellen zu steigern, ist es oft besser, Pass-Through-Abfragen zu schreiben, aber das würde den Rahmen dieses Artikels sprengen.

Schlechte Vorzeichen

In showplan.out gibt es ein paar schlechte Zeichen, auf die man achten sollte Datei. Das einfache Vorhandensein dieser Zeichen bedeutet nicht unbedingt, dass ein Problem vorliegt. Wenn Sie jedoch eine Abfrage mit schlechter Leistung beheben, können Sie sich diese Wörter als Warnhinweise für potenzielle Probleme vorstellen:X-Prod , scanning , temp , temporary .

Der X-Prod Das Schlüsselwort wird angezeigt, wenn Sie eine Abfrage mit einem kartesischen Join haben (auch bekannt als Cross Join oder Cross Product). Dies geschieht normalerweise versehentlich, wenn Sie vergessen, zwei Tabellen im Query-by-Example (QBE)-Editor zu verknüpfen. Das Ergebnis ist, dass jeder Datensatz in Tabelle 1 mit jedem Datensatz in Tabelle 2 abgeglichen wird. Die Gesamtzahl der Datensätze ist das Produkt der beiden Tabellenzählungen. Wenn also Tabelle 1 7 Datensätze und Tabelle 2 9 Datensätze enthält, gibt die Kreuzverknüpfung der beiden Tabellen 63 Datensätze zurück. Sie können sich das Problem vorstellen, wenn beide Tabellen Tausende von Datensätzen oder mehr enthalten.

01) Inner Join table 'Table1' to table 'Table2'
      using X-Prod join

Das nächste Schlüsselwort, auf das Sie achten sollten, ist Scannen . Wenn die Datenbank-Engine keinen Index verwenden kann, um Ergebnisse zu filtern, greift sie auf das Scannen zurück. Das bedeutet, dass jede Zeile einzeln untersucht werden muss, um festzustellen, ob sie die Abfragekriterien erfüllt. Wenn Sie dieses Wort in einem showplan.out sehen -Datei bedeutet dies oft, dass Sie der zu scannenden Spalte einen Index hinzufügen müssen. Aber nicht immer! Für Spalten mit niedriger Kardinalität (nur wenige eindeutige Werte, z. B. eine Statusspalte), hat das Hinzufügen eines Index normalerweise wenig Vorteile. Nach dem Hinzufügen muss der Index beibehalten werden. Dadurch werden Einfügungen verlangsamt und Speicherplatz belegt. Wenn die Abfrageleistung für Produktionsdaten akzeptabel ist, ist das Hinzufügen eines Index zur gescannten Spalte außerdem eine verfrühte Optimierung (die Sie vermeiden sollten).

Schließlich gibt es noch die temp und temporär Schlüsselwörter. Diese weisen darauf hin, dass die Datenbank-Engine vorübergehend irgendeine Art von Operation ausführen musste. Wenn wir eine Querydef erstellen und speichern, wird dieses Objekt mit bestimmten Metadaten gespeichert, um die wiederholte Ausführung zu optimieren. Offensichtlich gehen solche Metadaten verloren, wenn temporäre Indizes oder Verknüpfungen den Gültigkeitsbereich verlassen. Diese Schlüsselwörter können normalerweise ignoriert werden, aber sie können Sie möglicherweise in die richtige Richtung weisen, wenn Sie bei einer Abfrage mit schlechter Leistung ohne andere offensichtlichere Mängel stecken bleiben.

Vereinfacht zusammengefasst:

      GUT  >  >  >  >  >  SCHLECHT:
Rushmore> indexes> temp/temporary> scannen> X-Prod

Benutzerdefinierte Notepad++-Sprache

Wenn Sie meine andere Arbeit gelesen haben, wissen Sie, dass ich starke Gefühle für die Erhöhung des Signal-Rausch-Verhältnisses beim Programmieren (und im Leben im Allgemeinen) habe. Zu diesem Zweck habe ich in Notepad++ eine "benutzerdefinierte Sprache"-Datei erstellt, um showplan.out eine Syntaxhervorhebung hinzuzufügen Dateien. Jetzt, wenn ich showplan.out öffne Dateien sehen sie wie im Screenshot unten aus. Die „GUTEN“ Schlüsselwörter sind in blauem Text und die „SCHLECHTIGEN“ Schlüsselwörter in rotem Text gefärbt. Dies ist ein Beispiel dafür, wie man falschen Code falsch aussehen lässt.

Gehen Sie folgendermaßen vor, um dies einzurichten:

  1. Öffnen Sie Notepad++
  2. Sprache -> Benutzerdefinierte Sprache -> Definiere deine Sprache...
  3. Klicken Sie auf [Neu erstellen...]
  4. Geben Sie den Namen ein:showplan.out
  5. Klicken Sie auf [OK]
  6. Gehen Sie zu _| Ordner &Standard|_ Registerkarte
  7. Geben Sie unter "Folding in Code 2 style" Inputs ein für Öffnen und End inputs für Schließen
  8. Gehen Sie zur Registerkarte _|Keyword-Liste|_
  9. Klicken Sie unter der ersten Gruppe auf [Styler] und setzen Sie die Vordergrundfarbe auf Rot
  10. Geben Sie die folgenden "BAD"-Keywords in die 1. Gruppe ein:
    temp temporary scanning X-Prod
  11. Klicken Sie unter der zweiten Gruppe auf [Styler] und setzen Sie die Vordergrundfarbe auf Blau
  12. Geben Sie die folgenden "GOOD"-Keywords in die 2. Gruppe ein:
    rushmore index
  13. Geben Sie Ext.:out ein

Abschließende Gedanken

Im Gegensatz zu SQL Server erlaubt Ihnen das Jet/ACE-Datenbankmodul nicht, Abfrageausführungspläne direkt zu ändern. Das heißt, wir können mit JetShowPlan in die Blackbox schauen, aber wir können sie nicht neu verkabeln, um zu tun, was wir wollen. Stattdessen müssen wir uns auf das konzentrieren, was wir kontrollieren können:das genaue SQL, mit dem wir es füttern, und die Indizes und Beziehungen zwischen den beteiligten Tabellen.

Die Verwendung von JetShowPlan hat sowohl kurz- als auch langfristige Vorteile. Kurzfristig können Sie mit dieser Funktion Engpässe in Ihren Access-Anwendungen beheben. Langfristig erhalten Sie Einblicke in das Innenleben von Access, was Ihnen hilft, Engpässe von vornherein zu vermeiden.