Access
 sql >> Base de données >  >> RDS >> Access

JetShowPlan :une introduction

J'ai écrit brièvement sur JetShowPlan dans mon article sur Tuning Access Query Performance. Comme je l'ai écrit dans cet article, SQL est un langage déclaratif. Lorsque vous écrivez une requête, vous indiquez au moteur de base de données ce que vous voulez. Le moteur de base de données décide comment préférable d'accomplir cela pour vous. C'est généralement une bonne chose, car l'optimisation des opérations basées sur les ensembles est difficile et laisser le moteur de base de données le faire pour vous vous permet de tirer parti des connaissances de ceux qui consacrent leur vie à ce problème spécifique.

L'inconvénient est que le comment devient une boîte noire. Vous introduisez du SQL dans la boîte noire et un ensemble de résultats avec un tas de données en sort. Le moteur de base de données est extrêmement fiable pour vous fournir exactement les données que vous avez demandées. Le problème est que les performances de la récupération des données peuvent être omniprésentes. Pour être clair, les mauvaises performances ne sont presque jamais la faute du moteur de base de données. Habituellement, le problème est qu'il nous manque un index ou un filtrage sur le résultat d'une fonction VBA ou une jointure sur deux tables liées qui sont stockées dans des emplacements physiquement séparés.

Lorsque ce problème survient, nous avons besoin d'un moyen de le résoudre. Entrez JetShowPlan. Considérez cela comme un tournevis spécial qui nous permet de démonter la boîte noire et de regarder à l'intérieur pour voir comment le moteur de base de données implémente les commandes SQL que nous lui fournissons. Avec cette connaissance, nous pouvons modifier le SQL, ajouter un index ou autrement traiter la source de notre goulot d'étranglement de performance.

Commençons.

Clé de registre

JetShowPlan fonctionne en écrivant le plan de requête (c'est-à-dire le contenu de la boîte noire) dans un fichier texte chaque fois que le moteur de base de données ACE/Jet exécute tout requête. Ce fichier texte se remplit rapidement. La création du fichier texte nécessite des ressources qui nuisent davantage aux performances de la requête. Ainsi, nous ne voulons activer cette fonctionnalité que lorsque nous dépannons activement un problème.

Comme il s'agit d'un outil pour les utilisateurs avancés, il n'y a pas de paramètre dans l'interface utilisateur Access pour activer ce mode. La seule façon de l'activer ou de le désactiver consiste à définir une valeur dans le registre. La valeur de registre correspond au modèle suivant (le texte à l'intérieur des accolades sert d'espace réservé) :

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

Considérations sur la version et le nombre de bits

Le modèle de valeur de registre que j'ai montré ci-dessus utilise un texte d'espace réservé pour tenir compte des différences entre les environnements Access. Le texte du numéro de version \{xx}.0\ doit être remplacé par le numéro de version qui correspond à la version d'Access installée sur votre machine :

  • 12.0 :Accès 2007
  • 13.0  :ignoré pour éviter de déclencher des triskaidekaphobes
  • 14.0 :Accès 2010
  • 15.0 :Accès 2013
  • 16.0 :Accès 2016 &2019

Le \Wow6432Node ("Wow" signifie "Windows 32 bits sur Windows 64 bits") n'est requis que si vous exécutez une version 32 bits de Microsoft Access sur une version 64 bits de Windows. Si Access et Windows sont tous les deux en 32 bits ou en 64 bits, alors ce "dossier" (ou "clé" dans le jargon du registre) n'est pas nécessaire.

Au format VBA :

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

Par exemple, une installation 32 bits d'Access 2010 exécutée sur Windows 64 bits nécessiterait l'entrée de registre suivante :

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

De même, une installation 64 bits d'Access 2019 sur Windows 64 bits nécessiterait :

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

Je dois également noter que la première fois que vous créez cette entrée, vous devrez probablement ajouter la clé "Debug" (dossier) et le nom et les données de la valeur JETSHOWPLAN.

Voici les étapes à suivre :

  1. Exécutez regedit en tant qu'administrateur
  2. Naviguez jusqu'à la touche "\Engines" en suivant les notes ci-dessus
  3. Cliquez avec le bouton droit de la souris sur "\Engines" et choisissez Nouveau -> Clé
  4. Renommer la clé de "New Key #1" à "Debug"

Ensuite, vous devrez ajouter la valeur de chaîne "JETSHOWPLAN" avec les données "ON " pour activer l'ajout à showplan.out fichier ou "OFF " pour arrêter d'ajouter au fichier.

  1. Cliquez avec le bouton droit sur la touche "\Debug" et choisissez Nouveau -> Valeur de chaîne
  2. Renommer la valeur de "Nouvelle valeur #1" en "JETSHOWPLAN"
  3. Cliquez avec le bouton droit sur le nom de la valeur "JETSHOWPLAN" et choisissez Modifier...
  4. Définir les données de valeur sur ON puis cliquez sur le bouton [OK]

La prochaine fois que vous démarrerez une nouvelle instance d'Access, elle commencera à ajouter des données au fichier Showplan.out. Toutes les instances d'Access déjà en cours d'exécution lorsque vous apportez les modifications ci-dessus ne seront pas affectées. Il en va de même lorsque vous désactivez le paramètre OFF . Les modifications ne prennent effet que lorsque vous démarrez un nouveau msaccess.exe exemple. Il n'est pas nécessaire de fermer les instances existantes d'Access; il est possible d'avoir une instance ouverte d'Access qui écrit activement dans showplan.out alors qu'une autre instance d'Access ne l'est pas.

Script de raccourci clavier automatique

je ne vais pas mentir; sauter dans regedit chaque fois que je veux activer ou désactiver JetShowPlan, c'est ennuyeux. Si je devais le faire, je ne m'en soucierais guère. Mais je n'ai pas à faire ça ! J'ai créé un raccourci clavier dans Autohotkey qui active et désactive 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

Maintenant, lorsque je veux régler mes requêtes, j'appuie sur [Ctl] + [Win] + [Q] et je vois une boîte de message indiquant "JetShowPlan défini sur ON". Lorsque j'ai terminé, je ferme Access, j'appuie sur [Ctl] + [Win] + [Q] et je vois "JetShowPlan réglé sur OFF".

Ajustement des autorisations

J'ai deux comptes utilisateur Windows différents :l'un avec des autorisations standard que j'utilise pour le travail quotidien et l'autre avec des autorisations d'administrateur pour l'installation de logiciels, etc. Il s'agit d'une bonne pratique courante en matière de sécurité.

Le problème est que la clé de registre JetShowPlan se trouve dans la ruche HKLM. Par défaut, seuls les administrateurs peuvent modifier les valeurs de cette ruche. C'est ennuyeux car lorsque j'essaie d'exécuter mon script Autohotkey, j'obtiens le message d'erreur suivant :

Ne vous inquiétez pas, cependant. Comme le message ci-dessus le suggère, nous pouvons résoudre ce problème. La meilleure partie est que nous pouvons le rendre pratique sans réduire notre posture de sécurité. Voici l'astuce.

  1. Ouvrir regedit en tant qu'administrateur
  2. Naviguez jusqu'à \Debug clé
  3. Cliquez avec le bouton droit sur \Debug clé et choisissez Autorisations...
  4. Cliquez sur le bouton [Ajouter...]
  5. Entrez le nom d'utilisateur dans la boîte de message ci-dessus ("Mike"), cliquez sur [Vérifier les noms], puis cliquez sur [OK]
  6. Autoriser [√] "Contrôle total" pour l'utilisateur
  7. Cliquez sur [OK] pour enregistrer les modifications

Maintenant, lorsque j'appuie sur [Ctl] + [Win] + [Q], JetShowPlan est activé et désactivé, mettant à jour le registre automatiquement.

Trouver Showplan.out

Access ne vous avertira pas de l'endroit où le moteur de base de données Jet/ACE ajoute les informations du plan de requête lorsque JetShowPlan est activé. J'ai passé plus de temps que je ne veux l'admettre à chercher une copie malveillante de showplan.out . Cette section vous évitera de partager ce destin.

Emplacement par défaut

Le premier endroit à regarder est le dossier Documents de l'utilisateur actuel. Par exemple, mon nom d'utilisateur Windows est "Mike", donc le premier endroit où je m'attendrais à trouver le fichier est :C:\Users\Mike\Documents\showplan.out .

Utilisation de CurDir()

Techniquement parlant, le showplan.out Le fichier est créé dans le répertoire de travail courant. Il s'agit généralement du dossier Documents de l'utilisateur actuel, mais pas toujours. Le moyen infaillible de trouver l'emplacement du fichier est d'utiliser le CurDir() fonction.

Vous pouvez copier, coller et exécuter la ligne de code suivante dans la fenêtre immédiate de VBA IDE pour ouvrir le fichier showplan.out (en supposant que vous avez activé JetShowPlan dans le registre) :

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

Modification de l'emplacement de sortie via ChDir()

Si, pour une raison quelconque, vous vouliez spécifier un emplacement différent pour le showplan.out fichier, vous pouvez le faire en utilisant la fonction ChDir(). Cette fonction change le répertoire de travail courant. Et, comme je l'ai mentionné plus tôt, le répertoire actuel est l'endroit où le showplan.out fichier réside. Dès que vous modifiez le répertoire de travail actuel, JetShowPlan commence à écrire dans le nouveau dossier ; il n'est pas nécessaire de fermer et de rouvrir Access.

Pourquoi pourriez-vous vouloir faire cela ? Supposons que vous vouliez comparer trois approches différentes pour récupérer les mêmes données. Vous écrivez trois requêtes différentes pour voir comment les modifications que vous apportez affectent le plan de requête. Depuis showplan.out est si verbeux, ce serait bien d'avoir chaque plan de requête dans son propre fichier. Cela facilitera la comparaison des plans de requête. Voici comment je pourrais faire ça. La première étape consiste à s'assurer que chacun de ces dossiers existe. Ensuite, exécutez les lignes de code suivantes :

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"

Utilisez tout ce que vous avez (ou téléchargez-le si vous ne je ne l'ai pas encore)

Alors que CurDir() vous donnera un emplacement définitif pour les modifications les plus récentes apportées à showplan.out file, il ne peut pas vous dire quels étaient les répertoires de travail précédents. Et, si vous avez fermé l'instance d'Access qui a créé le showplan.out fichier, il n'y a aucune garantie que la prochaine instance d'Access que vous ouvrirez aura le même répertoire actuel.

Je suis récemment tombé sur un petit utilitaire très pratique appelé "Everything". C'est un petit exécutable qui indexe tout votre disque dur en quelques secondes. Une fois l'indexation terminée, vous pouvez rechercher instantanément des fichiers ou des dossiers n'importe où sur votre disque.

Vous pouvez télécharger Tout d'ici ou via Chocolatey :choco install everything . Ouvrir Tout , recherchez showplan.out , et en moins d'une seconde, vous verrez chaque instance de showplan.out sur votre ordinateur avec la date de la dernière modification. J'aurais aimé avoir cet outil il y a des années.

Comprendre Showplan.out

La première fois que vous ouvrez un showplan.out fichier, attendez-vous à être déconcerté. Il y a beaucoup de texte et une grande partie est du bruit. Voici un extrait d'un fichier généré lorsque j'ai ouvert l'exemple de base de données Northwind :

Les requêtes commençant par un tilde (~ ) représentent le SQL brut enregistré dans la feuille de propriétés d'un formulaire ou d'un état et non enregistré en tant qu'objet QueryDef permanent. Les principaux points d'intérêt sont les étapes numérotées pour chaque requête :01) , 02) , 03) , etc.  Vous souhaitez suivre ces étapes à la recherche de bons et de mauvais signes qui pourraient indiquer où il y a des problèmes.

A ma connaissance, il n'y a pas de documentation officielle pour le formatage et le contenu de showplan.out dossier. Ce n'est pas grave, car nous n'allons pas nous perdre dans les détails. Notre objectif principal est d'identifier les problèmes les plus évidents et de les résoudre. La règle du 80/20 s'applique ici. La plupart des gains de performances proviendront d'un ou deux ajustements simples à nos requêtes.

Bons signes

Tout est question d'index. Nous voulons que le plan de requête utilise des index, en particulier dans les premières étapes d'une requête en plusieurs étapes. Deux mots clés différents indiquent que des index sont utilisés :index et rushmore . Rushmore est le nom de code de la technologie d'optimisation des requêtes développée à l'origine par Fox Software au début des années 1980. Microsoft a acheté la société en 1992 et a intégré la technologie dans le moteur de base de données Jet.

Les requêtes qui utilisent la technologie Rushmore pour traiter les index s'exécutent plus rapidement que celles qui utilisent les index de manière plus traditionnelle. La technologie Rushmore ne peut être utilisée qu'avec des tables Access (locales et liées), ainsi qu'avec des tables FoxPro et dBASE liées. Notamment, Rushmore ne peut pas être utilisé avec des tables SQL Server liées. Pour améliorer les performances des tables SQL Server liées, il est souvent préférable d'écrire des requêtes directes, mais cela dépasse le cadre de cet article.

Mauvais signes

Il y a quelques mauvais signes à surveiller dans le showplan.out dossier. La simple présence de ces signes ne signifie pas nécessairement qu'il y a un problème. Cela dit, si vous dépannez une requête avec de mauvaises performances, vous pouvez considérer ces mots comme des signaux d'avertissement pour des problèmes potentiels :X-Prod , scanning , temp , temporary .

Le X-Prod Le mot-clé apparaît lorsque vous avez une requête avec une jointure cartésienne (également appelée jointure croisée ou produit croisé). Cela se produit généralement par erreur lorsque vous oubliez de joindre deux tables dans l'éditeur Query-by-Example (QBE). Le résultat est que chaque enregistrement de la table 1 est mis en correspondance avec chaque enregistrement de la table 2. Le nombre total d'enregistrements est le produit des deux nombres de tables. Ainsi, si la table 1 contient 7 enregistrements et que la table 2 en contient 9, la jointure croisée des deux tables renvoie 63 enregistrements. Vous pouvez imaginer le problème si les deux tables ont des milliers d'enregistrements ou plus.

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

Le prochain mot-clé à surveiller est balayage . Si le moteur de base de données ne peut pas utiliser un index pour filtrer les résultats, il revient à l'analyse. Cela signifie qu'il doit examiner chaque ligne individuellement pour voir si elle répond aux critères de requête. Lorsque vous voyez ce mot dans un showplan.out fichier, cela signifie souvent que vous devez ajouter un index à la colonne en cours d'analyse. Mais pas toujours! Pour les colonnes à faible cardinalité (seulement quelques valeurs uniques, comme une colonne d'état), il y a généralement peu d'avantages à ajouter un index. Une fois ajouté, l'index doit être maintenu. Cela ralentit les insertions et occupe de l'espace disque. De plus, si les performances de la requête sont acceptables sur les données de production, l'ajout d'un index à la colonne analysée est une optimisation prématurée (que vous devez éviter).

Enfin, il y a les temp et temporaire mots clés. Ceux-ci indiquent que le moteur de base de données a dû effectuer une sorte d'opération sur une base temporaire. Lorsque nous créons et enregistrons un querydef, cet objet est enregistré avec certaines métadonnées pour optimiser l'exécution répétée. De toute évidence, ces métadonnées sont perdues lorsque des index ou des jointures temporaires sortent de la portée. Ces mots clés peuvent généralement être ignorés, mais ils peuvent vous orienter dans la bonne direction si vous êtes bloqué sur une requête peu performante sans autre défaut plus évident.

Pour résumer en termes trop simplifiés :

      BON  >  >  >  >  >  MAUVAIS :
Rushmore> index> temp/temporary> scanning> X-Prod

Langage personnalisé de Notepad++

Si vous avez lu mes autres travaux, vous savez que j'ai des sentiments forts à propos de l'augmentation du rapport signal sur bruit dans la programmation (et la vie en général). À cette fin, j'ai créé un fichier "Langage défini par l'utilisateur" dans Notepad++ pour ajouter la coloration syntaxique à showplan.out des dossiers. Maintenant, quand j'ouvre showplan.out fichiers, ils ressemblent à la capture d'écran ci-dessous. Les mots clés "BONS" sont colorés en texte bleu et les mots clés "MAUVAIS" sont colorés en texte rouge. Il s'agit d'un exemple de création d'un code erroné.

Pour le configurer, procédez comme suit :

  1. Ouvrir le Bloc-notes++
  2. Langue -> Langue définie par l'utilisateur -> Définissez votre langue...
  3. Cliquez sur [Créer nouveau...]
  4. Entrez le nom :showplan.out
  5. Cliquez sur [OK]
  6. Allez au _| Dossier &Défaut|_ onglet
  7. Sous "Pliage dans le style code 2", saisissez Inputs pour les entrées Open et End inputs pour Fermer
  8. Accédez à l'onglet _|Liste des mots clés|_
  9. Cliquez sur [Styler] sous le 1er groupe et définissez la couleur de premier plan sur rouge
  10. Entrez les mots clés "MAUVAIS" suivants dans le 1er groupe :
    temp temporary scanning X-Prod
  11. Cliquez sur [Styler] sous le 2e groupe et définissez la couleur de premier plan sur bleu
  12. Saisissez les mots clés "BON" suivants dans le 2e groupe :
    rushmore index
  13. Entrez Ext. :out

Réflexions finales

Contrairement à SQL Server, le moteur de base de données Jet/ACE ne vous permet pas de modifier directement les plans d'exécution des requêtes. Cela signifie que nous pouvons regarder à l'intérieur de la boîte noire avec JetShowPlan, mais nous ne pouvons pas la recâbler pour faire ce que nous voulons. Au lieu de cela, nous devons nous concentrer sur ce que nous pouvons contrôler :le code SQL exact que nous lui fournissons, ainsi que les index et les relations entre les tables concernées.

L'utilisation de JetShowPlan présente des avantages à court et à long terme. À court terme, la fonctionnalité vous permet de résoudre les goulots d'étranglement dans vos applications Access. À long terme, vous obtenez un aperçu du fonctionnement interne d'Access, ce qui vous aide à éviter les goulots d'étranglement.