速度を犠牲にする「その場しのぎ」は卒業せよ。DAOによる動的インデックス制御の極意
Access開発の現場で、一時テーブルを多用する設計に出会うことは多い。しかし、多くの開発者が犯す決定的なミスがある。それは、「大量データを一時テーブルに放り込み、インデックスを貼らずに検索・集計を行う」という怠慢だ。
`DLookup`やフィルタリングが遅いと嘆く前に、データベースの物理構造を見直せ。今回は、VBAからDAOを駆使して動的にインデックスを構築・破壊する、プロフェッショナルのためのチューニング手法を伝授する。
—
なぜ「静的」な設定ではいけないのか
一時テーブルを毎回テーブル定義から作成し直すのは、保守性の観点から「負債」でしかない。
真のアーキテクトは、「空の雛形テーブル(テンプレート)」を配置し、実行時に必要なインデックスのみを動的に追加・削除する。これにより、実行時のデータ量や検索条件に合わせた「最適な物理パス」をその都度生成できるのだ。
DAOによるインデックス制御の鉄則
1. オブジェクトの破棄を忘れるな: DAOオブジェクト(TableDef, Index)は明示的にNothingを代入し、メモリリークを塞げ。
2. エラーハンドリングは「存在確認」で: インデックスが存在しない状態で削除しようとすると容赦なくエラーが飛ぶ。`Indices`コレクションを走査する防衛コードが必須だ。
—
実践:堅牢なインデックス制御モジュール
以下は、実務でそのまま使える汎用関数だ。`DAO.Index`オブジェクトのライフサイクルを完全に掌握したコードである。
Option Compare Database
Option Explicit
‘ @brief インデックスを動的に付与・削除するアーキテクチャ
‘ @param TableName 対象テーブル名
‘ @param IndexName インデックス名
‘ @param FieldName インデックス対象フィールド名(複数可)
‘ @param IsUnique ユニーク制約の有無
Public Sub ManageIndex(ByVal TableName As String, _
ByVal IndexName As String, _
ByVal FieldName As String, _
Optional ByVal IsUnique As Boolean = False)
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim idx As DAO.Index
Dim fld As DAO.Field
Set db = CurrentDb
Set tdf = db.TableDefs(TableName)
‘ 1. 既存インデックスがある場合は削除(再構築を前提とする)
On Error Resume Next
tdf.Indexes.Delete IndexName
On Error GoTo 0
‘ 2. インデックスオブジェクトの作成
Set idx = tdf.CreateIndex(IndexName)
idx.Unique = IsUnique
‘ 3. フィールドの紐付け
Set fld = idx.CreateField(FieldName)
idx.Fields.Append fld
‘ 4. テーブルへの追加
tdf.Indexes.Append idx
‘ 5. クリーンアップ(非常に重要)
Set fld = Nothing
Set idx = Nothing
Set tdf = Nothing
Set db = Nothing
End Sub
—
現場で刺さる「運用の勘所」
コードをコピペするだけでは一流ではない。現場でトラブルを起こさないための「知見」を共有する。
1. インデックスの「貼りすぎ」は毒
インデックスは検索を高速化するが、書き込み(INSERT/UPDATE)のコストを激増させる。一時テーブルに大量のデータを書き込む際は、以下の順序を厳守せよ。
1. データ挿入
2. インデックス作成
3. 検索処理
4. インデックス削除
この手順を踏むだけで、全体の処理時間は劇的に短縮される。
2. インデックス名の衝突を回避する
複数の処理から同じ一時テーブルを呼ぶ場合、インデックス名が競合する可能性がある。運用時は `idx_TempProcessA_UserID` のように、プロセスIDやタイムスタンプを付与した命名規則を徹底することをお勧めする。
3. DAOの「重み」を知る
`CurrentDb`を安易に何度も呼ぶな。`CurrentDb`は呼び出すたびに新しいインスタンスを生成する可能性があるため、プロシージャの冒頭で変数に格納し、使い回すのがパフォーマンスの定石だ。
—
結論:技術の背景にある「思想」を持て
Access VBAはレガシーと言われることもある。だが、このようにDAOを極め、データベースの物理層まで制御するエンジニアにとって、それは強力な武器であり続ける。
「なぜこの処理が遅いのか?」
そう問い続け、インデックスを動的に操ることで、ユーザーの待機時間を0.1秒でも削り取る。それが、我々エンジニアが担うべき「業務自動化の美学」である。
君の作るツールが、単なるプログラムではなく、ユーザーの業務を根本から変えるソリューションとなることを期待している。
