【Access極限最適化】不要インデックスを撲滅せよ:VBAによるパフォーマンスチューニングの真髄
「Accessが重い」「新規レコードの保存に時間がかかる」。
現場からそんな悲鳴が上がったとき、多くの初心者はフォームのクエリを疑う。だが、熟練のアーキテクトが真っ先にメスを入れるのは、「肥大化したインデックス」だ。
インデックスは検索速度を劇的に向上させる魔法だが、書き込み(INSERT/UPDATE)においては毒となる。B-Tree構造を維持するために、レコードを追加するたびにAccessは全インデックスを再構築するからだ。
今回は、使われていない(あるいは過剰な)インデックスをVBAで検出し、データベースのポテンシャルを解放する「外科手術」の作法を伝授する。
—
1. なぜ「インデックス」がボトルネックになるのか
インデックスは、データが挿入されるたびに「並び替え」と「平衡化」のコストを要求する。
- プライマリキー(PK): 必須。
- 外部キー(FK): リレーションシップの整合性維持に必須だが、過剰な場合は再考が必要。
- 検索用インデックス: これが曲者だ。過去の要件で作成されたまま、現在のクエリでは一切使われていないインデックスが、書き込み速度を削り続けている。
2. インデックス診断の論理設計
DAO(Data Access Objects)を使えば、テーブルのメタデータをプログラムから操作できる。`TableDef` オブジェクトから `Indexes` コレクションを走査し、システムインデックス(プライマリキー等)を除外した「ユーザー定義インデックス」を抽出するのが戦略だ。
以下のコードは、「どのテーブルに、どのフィールドでインデックスが張られているか」をイミディエイトウィンドウに出力する診断ツールである。
‘ ———————————————————————-
‘ プロシージャ名: DiagnoseTableIndexes
‘ 概要: データベース内の全テーブルからインデックス構成を一覧化する
‘ ———————————————————————-
Public Sub DiagnoseTableIndexes()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim idx As DAO.Index
Dim fld As DAO.Field
Set db = CurrentDb
Debug.Print “— インデックス診断レポート —”
For Each tdf In db.TableDefs
‘ システムテーブル(MSys…)は除外
If Left(tdf.Name, 4) <> “MSys” Then
For Each idx In tdf.Indexes
‘ プライマリキーは除外して診断対象とする
If Not idx.Primary Then
Debug.Print “Table: ” & tdf.Name & ” | Index: ” & idx.Name
For Each fld In idx.Fields
Debug.Print vbTab & “Field: ” & fld.Name
Next fld
End If
Next idx
End If
Next tdf
Set db = Nothing
MsgBox “診断が完了しました。イミディエイトウィンドウを確認してください。”, vbInformation
End Sub
—
3. 実行時の「落とし穴」と保守性への配慮
このスクリプトを運用する際、以下の3点に注意せよ。これができない者は、本番環境で事故を起こす。
1. 排他制御の徹底:
`TableDef` を操作する際は、ユーザーが他のフォームでそのテーブルを開いているとエラーになる。必ずDAOでデータベースを明示的に開き、適切なエラーハンドリングを実装すること。
2. 削除は慎重に:
コードでインデックスを削除する `tdf.Indexes.Delete “インデックス名”` を実装したくなるだろう。だが、「削除する前に必ずバックアップを取る」こと。そして、そのインデックスが本当に使用されていないか、クエリの実行計画を `EXPLAIN` 的な観点(クエリプランの確認)で精査するプロセスを忘れてはならない。
3. リレーションシップの罠:
「リレーションシップの設定」で作成されたインデックスは、VBAから単純に削除できない場合がある。まずはUI上でリレーションシップを確認し、不要なものを手動で消してから、残った「野良インデックス」をVBAで一掃するのが定石だ。
4. アーキテクトからの提言
パフォーマンス改善の本質は、「足すこと」ではなく「削ること」にある。
多くの開発者は、不安から「とりあえずインデックスを貼る」という逃げの設計を行う。しかし、真のプロは「クエリがインデックスを必要としているか」を証明してから実装する。
まずは上記の診断スクリプトで、あなたのDBの中に眠る「使われないインデックス」の正体を突き止めろ。それが、あなたのシステムを高速化させる第一歩だ。コードは道具に過ぎない。重要なのは、その裏にあるデータの流れを読み解く「視座」であることを忘れないでほしい。
—
次回のトピック:
「DAOの `Recordset` を使いこなし、バルクインサートで書き込み速度を極限まで引き上げる手法」について解説する。期待していてくれ。
