アクセスクエリのパフォーマンスの調整に関する記事で、JetShowPlanについて簡単に説明しました。その記事で書いたように、SQLは宣言型言語です。クエリを作成するときは、データベースエンジンに何を伝えていることになります。 あなたが欲しい。データベースエンジンが方法を決定します あなたのためにそれを達成するのが最善です。セットベースの操作を最適化することは困難であり、データベースエンジンにそれを任せることで、その特定の問題に人生を捧げる人々の知識を活用できるため、これは一般的には良いことです。
欠点は、どのように ブラックボックスになります。いくつかのSQLをブラックボックスにフィードすると、大量のデータを含む結果セットが出力されます。データベースエンジンは、要求したデータを正確に提供する上で非常に信頼性があります。問題は、データ取得のパフォーマンスがいたるところにある可能性があることです。明確にするために、パフォーマンスの低下がデータベースエンジンの障害であるということはほとんどありません。通常、問題は、VBA関数の結果に対するインデックスまたはフィルタリングが欠落しているか、物理的に離れた場所に格納されている2つのリンクされたテーブルに結合していることです。
この問題が発生した場合、トラブルシューティングを行う方法が必要です。 JetShowPlanと入力します。これは、ブラックボックスを分解して内部を覗き込み、方法を確認できる特別なドライバーと考えてください。 データベースエンジンは、フィードするSQLコマンドを実装しています。この知識があれば、SQLを微調整したり、インデックスを追加したり、パフォーマンスのボトルネックの原因に対処したりできます。
始めましょう。
JetShowPlanは、ACE/Jetデータベースエンジンがanyを実行するたびに、クエリプラン(つまり、ブラックボックスの内容)をテキストファイルに書き込むことで機能します。 クエリ。このテキストファイルはすぐにいっぱいになります。テキストファイルを作成するには、クエリのパフォーマンスをさらに低下させるリソースが必要です。したがって、問題のトラブルシューティングを積極的に行っている場合にのみ、この機能を有効にします。
これは上級ユーザー向けのツールであるため、Accessユーザーインターフェイスにこのモードを有効にする設定はありません。オンまたはオフにする唯一の方法は、レジストリに値を設定することです。レジストリ値は次のパターンに適合します(中括弧内のテキストはプレースホルダーとして機能します):
[HKEY_LOCAL_MACHINE\SOFTWARE{\Wow6432Node}\Microsoft\Office\{xx}.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"
上で示したレジストリ値のパターンでは、Access環境間の違いを説明するためにプレースホルダーテキストを使用しています。バージョン番号のテキスト\{xx}.0\
マシンにインストールされているAccessのバージョンに対応するバージョン番号に置き換える必要があります:
-
12.0
:Access 2007 -
13.0
:triskaidekaphobesのトリガーを回避するためにスキップ -
14.0
:Access 2010 -
15.0
:アクセス2013 -
16.0
:2016年と2019年にアクセス
\Wow6432Node
(「Wow」は「Windows64ビット上のWindows 32ビット」を表します)は、64ビットバージョンのWindowsで32ビットバージョンのMicrosoftAccessを実行している場合にのみ必要です。 AccessとWindowsが両方とも32ビットまたは両方とも64ビットの場合、その「フォルダ」(またはレジストリ用語の「キー」)は不要です。
VBA形式:
If Is32BitAccess Xor Is32BitWindows Then
IncludeWow6432Key = True
Else
IncludeWow6432Key = False
End If
たとえば、64ビットWindowsで実行されているAccess 2010の32ビットインストールには、次のレジストリエントリが必要です。
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"
同様に、64ビットWindowsにAccess 2019を64ビットインストールするには、次のものが必要です。
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engine\Engines\Debug]
"JETSHOWPLAN"="ON"
また、このエントリを初めて作成するときに、「デバッグ」キー(フォルダ)とJETSHOWPLAN値の名前とデータを追加する必要がある可能性があることにも注意してください。
これを行う手順は次のとおりです。
- regeditを実行します 管理者として
- 上記の注意事項に従って「\Engines」キーに移動します
- 「\Engines」を右クリックして、「新規」->「キー」を選択します
- キーの名前を「新しいキー#1」から「デバッグ」に変更します
次に、「JETSHOWPLAN」文字列値にデータ「 ON」を追加する必要があります。 " showplan.outへの追加を有効にします ファイルまたは「オフ "ファイルへの追加を停止します。
- 「\Debug」キーを右クリックして、「新規」->「文字列値」を選択します
- 値の名前を「新しい値#1」から「JETSHOWPLAN」に変更します
- 「JETSHOWPLAN」の値の名前を右クリックして、「変更...」を選択します...
- 値データをオンに設定します 次に[OK]ボタンをクリックします
次にAccessの新しいインスタンスを開始すると、Showplan.outファイルへのデータの追加が開始されます。上記の変更を行ったときにすでに実行されているAccessのインスタンスは影響を受けません。設定をオフにした場合も同様です。 。新しいmsaccess.exeを開始するまで、変更は有効になりません。 実例。 Accessの既存のインスタンスを閉じる必要はありません。 Accessの別のインスタンスがそうではないのにshowplan.outにアクティブに書き込んでいるAccessの1つのオープンインスタンスを持つことが可能です。
私はうそをつくつもりはありません。 regeditにジャンプする JetShowPlanをオンまたはオフにしたいときはいつも面倒です。そうしなければならないのなら、ほとんど気になりません。しかし、私はそれをする必要はありません! JetShowPlanのオンとオフを切り替えるホットキーをAutohotkeyで作成しました。
^#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
クエリを調整するときに、[Ctl] + [Win] + [Q]を押すと、「JetShowPlanがONに設定されています」というメッセージボックスが表示されます。完了したら、Accessを閉じ、[Ctl] + [Win] + [Q]を押すと、「JetShowPlanがOFFに設定されています」と表示されます。
2つの異なるWindowsユーザーアカウントを持っています。1つは日常業務に使用する標準の権限を持ち、もう1つはソフトウェアのインストールなどの管理者権限を持っています。これは一般的なセキュリティのベストプラクティスです。
問題は、JetShowPlanレジストリキーがHKLMハイブにあることです。デフォルトでは、管理者のみがそのハイブの値を変更できます。 Autohotkeyスクリプトを実行しようとすると、次のエラーメッセージが表示されるため、これは煩わしいことです。
ただし、心配する必要はありません。上記のメッセージが示すように、これを修正できます。一番のメリットは、セキュリティ体制を崩すことなく便利にできることです。これがトリックです。
- regeditを開きます 管理者として
- \ Debugに移動します キー
- \ Debugを右クリックします キーを押して[権限]を選択します...
- [追加...]ボタンをクリックします
- 上のメッセージボックス(「マイク」)からユーザー名を入力し、[名前の確認]をクリックして、[OK]をクリックします
- ユーザーに[√]「フルコントロール」を許可する
- [OK]をクリックして変更を保存します
[Ctl] + [Win] + [Q]を押すと、JetShowPlanのオンとオフが切り替わり、レジストリが自動的に更新されます。
Showplan.outの検索
JetShowPlanが有効になっている場合、AccessはJet/ACEデータベースエンジンがクエリプラン情報を追加している場所を警告しません。 showplan.outの不正なコピーを検索することを認めるよりも多くの時間を費やしました。 。このセクションでは、その運命を共有する必要がなくなります。
最初に確認する場所は、現在のユーザーのDocumentsフォルダーです。たとえば、私のWindowsユーザー名は「Mike」なので、ファイルを最初に見つけると予想される場所は、C:\Users\Mike\Documents\showplan.out
です。 。
CurDir()の使用
技術的に言えば、 showplan.out ファイルは現在の作業ディレクトリに作成されます。これは通常、現在のユーザーのDocumentsフォルダーですが、常にそうとは限りません。ファイルの場所を見つける確実な方法は、 CurDir()を使用することです。 機能。
VBA IDEイミディエイトウィンドウで次のコード行をコピー、貼り付け、実行して、showplan.outファイルを開くことができます(レジストリでJetShowPlanを有効にしている場合)。
Shell "notepad """ & CurDir & "\showplan.out""", vbNormalFocus
ChDir()を介して出力場所を変更する
何らかの理由でshowplan.outに別の場所を指定したい場合 ファイルの場合、ChDir()関数を使用してこれを行うことができます。この関数は、現在の作業ディレクトリを変更します。そして、前述したように、現在のディレクトリは showplan.outの場所です。 ファイルが存在します。現在の作業ディレクトリを変更するとすぐに、JetShowPlanは新しいフォルダへの書き込みを開始します。 Accessを閉じて再度開く必要はありません。
なぜあなたはこれをしたいのですか?同じデータを取得するための3つの異なるアプローチを比較したいとします。 3つの異なるクエリを記述して、行った変更がクエリプランにどのように影響するかを確認します。 showplan.out以降 非常に冗長なので、各クエリプランを独自のファイルに含めると便利です。これにより、クエリプランの比較が容易になります。これが私がそれを行う方法です。最初のステップは、これらの各フォルダーが存在することを確認することです。次に、次のコード行を実行します。
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"
持っているものをすべて使用する(または、持っていない場合はダウンロードする)まだ持っていません)
CurDir()は、 showplan.outへの最新の変更の決定的な場所を提供します。 ファイル、それはあなたに以前の作業ディレクトリが何であったかを伝えることができません。また、 showplan.outを作成したAccessのインスタンスを閉じた場合 ファイルの場合、次に開くAccessのインスタンスが同じ現在のディレクトリを持つという保証はありません。
私は最近、「Everything」と呼ばれる便利な小さなユーティリティに出くわしました。これは、ハードドライブ全体にわずか数秒でインデックスを付ける小さな実行可能ファイルです。インデックス作成が完了すると、ドライブ上の任意の場所でファイルやフォルダをすぐに検索できます。
すべてをダウンロードできます ここから、またはChocolatey経由:choco install everything
。 すべてを開く 、showplan.out
を検索します 、1秒以内に、コンピューター上のshowplan.outのすべてのインスタンスが、最終更新日とともに表示されます。何年も前にこのツールがあればよかったのに。
Showplan.outの意味を理解する
showplan.outを初めて開くとき ファイル、困惑することを期待してください。たくさんのテキストがあり、その多くはノイズです。 Northwindサンプルデータベースを開いたときに生成されたファイルからの抜粋を次に示します。
チルダで始まるクエリ(~
)フォームまたはレポートのプロパティシートに保存され、永続的なQueryDefオブジェクトとして保存されない生のSQLを表します。主な関心事は、各クエリの番号付きステップです:01)
、02)
、03)
、など。次の手順に従って、問題がある場所を示唆する可能性のある良い兆候と悪い兆候を探します。
私の知る限り、 showplan.outのフォーマットと内容に関する公式ドキュメントはありません。 ファイル。でも、細かな点にとらわれることはないので、大丈夫です。私たちの主な目標は、明白な問題を特定し、それらに対処することです。ここでは80/20の法則が適用されます。パフォーマンスの向上のほとんどは、クエリに対する1つまたは2つの簡単な調整によってもたらされます。
これはすべてインデックスに関するものです。特にマルチステップクエリの最初のステップでは、クエリプランでインデックスを使用する必要があります。 2つの異なるキーワードは、インデックスが使用されていることを示します。index
およびrushmore
。 Rushmoreは、1980年代初頭にFoxSoftwareによって最初に開発されたクエリ最適化テクノロジのコードネームです。 Microsoftは1992年に会社を買収し、このテクノロジをJetデータベースエンジンに組み込みました。
Rushmoreテクノロジを使用してインデックスを処理するクエリは、従来の方法でインデックスを使用するクエリよりも高速に実行されます。 Rushmoreテクノロジは、Accessテーブル(ローカルテーブルとリンクテーブルの両方)、およびリンクされたFoxProテーブルとdBASEテーブルでのみ使用できます。特に、RushmoreはリンクされたSQLServerテーブルでは使用できません。リンクされたSQLServerテーブルのパフォーマンスを向上させるには、パススルークエリを作成する方がよい場合がよくありますが、それはこの記事の範囲を超えています。
showplan.out には、注意すべきいくつかの悪い兆候があります。 ファイル。これらの兆候の単純な存在は、必ずしも問題があることを意味するわけではありません。とはいえ、パフォーマンスの低いクエリのトラブルシューティングを行っている場合は、次の単語を潜在的な問題の警告フラグと考えることができます:X-Prod
、scanning
、temp
、temporary
。
X-Prod キーワードは、デカルト結合(クロス結合またはクロス積とも呼ばれます)を使用したクエリがある場合に表示されます。これは通常、Query-by-Example(QBE)エディターで2つのテーブルを結合するのを忘れたときに誤って発生します。その結果、テーブル1のすべてのレコードが、テーブル2のすべてのレコードと一致します。レコードの総数は、2つのテーブルカウントの積になります。したがって、テーブル1に7つのレコードがあり、テーブル2に9つのレコードがある場合、2つのテーブルの相互結合は63のレコードを返します。両方のテーブルに数千以上のレコードがある場合、問題を想像できます。
01) Inner Join table 'Table1' to table 'Table2'
using X-Prod join
次に注意するキーワードはスキャンです。 。データベースエンジンがインデックスを使用して結果をフィルタリングできない場合、スキャンにフォールバックします。これは、各行を個別に調べて、クエリ基準を満たしているかどうかを確認する必要があることを意味します。 showplan.outにこの単語が表示された場合 ファイルの場合、スキャンする列にインデックスを追加する必要があることを意味します。しかしいつもではない! カーディナリティが低い列の場合 (ステータス列など、いくつかの一意の値のみ)、通常、インデックスを追加することにはほとんど利点がありません。追加したら、インデックスを維持する必要があります。これにより、挿入が遅くなり、ディスクスペースが占有されます。また、本番データでクエリのパフォーマンスが許容範囲内である場合、スキャンされた列にインデックスを追加することは時期尚早の最適化です(これは避ける必要があります)。
最後に、 tempがあります および一時的 キーワード。これらは、データベースエンジンが一時的に何らかの操作を実行する必要があったことを示しています。 querydefを作成して保存すると、繰り返し実行を最適化するために、そのオブジェクトが特定のメタデータとともに保存されます。明らかに、このようなメタデータは、一時的なインデックスまたは結合がスコープ外になると失われます。これらのキーワードは通常無視できますが、他に明らかな欠陥がなく、パフォーマンスの低いクエリに困惑した場合は、正しい方向を示すことができる場合があります。
過度に単純化した用語で要約するには:
良い>>>>悪い:
ラッシュモア>インデックス>一時的/一時的>スキャン>X-Prod
私の他の作品を読んでいるなら、プログラミング(そして一般的な生活)で信号対雑音比を上げることについて私が強い気持ちを持っていることをご存知でしょう。この目的のために、Notepad ++で「ユーザー定義言語」ファイルを作成して、 showplan.outに構文の強調表示を追加しました。 ファイル。さて、 showplan.outを開くと ファイルの場合、以下のスクリーンショットのようになります。 「GOOD」キーワードは青色のテキストで、「BAD」キーワードは赤色のテキストで色分けされています。これは、間違ったコードを間違って見せた例です。
これを設定するには、次の手順に従います。
- Notepad++を開く
- 言語->ユーザー定義言語->言語を定義...
- [新規作成...]をクリックします
- 名前を入力してください: showplan.out
- [OK]をクリックします
- _ |に移動します フォルダとデフォルト|_タブ
- [コード2スタイルで折りたたむ]の下に
Inputs
と入力します OpenおよびEnd inputs
の場合 クローズの場合 - _|キーワードリスト|_タブに移動
- 1番目のグループの下にある[スタイラー]をクリックし、前景色を赤に設定します
- 最初のグループに次の「BAD」キーワードを入力します。
temp temporary scanning X-Prod
- 2番目のグループの下にある[スタイラー]をクリックし、前景色を青に設定します
- 2番目のグループに次の「GOOD」キーワードを入力します。
rushmore index
- 内線を入力:外
SQL Serverとは異なり、Jet / ACEデータベースエンジンでは、クエリ実行プランを直接変更することはできません。つまり、JetShowPlanを使用してブラックボックスの内部を確認することはできますが、必要な処理を行うためにブラックボックスを再配線することはできません。代わりに、制御できるものに焦点を当てる必要があります。つまり、フィードする正確なSQLと、関連するテーブル間のインデックスと関係です。
JetShowPlanを使用すると、短期的および長期的なメリットがあります。短期的には、この機能を使用すると、Accessアプリケーションのボトルネックを修正できます。長期的には、Accessの内部動作についての洞察を得ることができ、そもそもボトルネックを回避するのに役立ちます。