50,000 通のメールをミリ秒で検索:MailVault のローカルインデックスの仕組み
MailVault に単語を入力すると、キーを押し終える前に新しい順の一致結果が画面に出ます。メールボックスが本当に大きくてもこれが成り立つのかを確かめるため、50,000 通の保管庫を作って検索時間を測りました。最も遅かったクエリでも 14 ミリ秒でした。
この記事では、実際の数値、何を測って何を測っていないか、そしてその裏にある技術、つまり保管庫の中にある小さくてシンプルな SQL データベースを紹介します。
テストの内容
実際のメールと同じマルチパートの HTML とプレーンテキストの形式で、1 通あたり約 3.3 KB のメッセージを 50,000 通生成しました。3 つのフォルダー(受信トレイ、アーカイブ、送信済み。それぞれおよそ 3 分の 1)に振り分け、既知の単語を既知の割合で仕込んでいます。「invoice」はメッセージの 5%、「budget」は 8%、「meeting」は 6% で、日本語やアクセント付きの単語も加えて、英語以外の検索も試しました。すべてのメッセージは、リリースビルドの MailVault の実際の MIME パーサーと実際のインデックス処理を通しています。
使ったマシンは、メモリ 16 GB の Apple M4 Mac mini です。アイドル状態ではなく、テスト中も他のビルドが動いていたので、この時間は負荷のかかったコンピューターでの結果と考えてください。各クエリは 6 回実行しました。修正を入れた作業用ビルドで 3 回、マージ後のコードで 3 回です。下の数値はその実行全体の範囲で、各時間には検索と、一覧に表示される結果行の組み立てが含まれます。
結果
50,000 messages · Apple M4 · warm cache · 6 runs each
query matches rows shown time
invoice ~2,500 500 7.1 – 7.5 ms
budget meeting 246 246 13.4 – 14.1 ms
update 4999 15 15 13.5 – 14.0 ms
会議 (Japanese) 1,529 500 4.3 – 4.6 ms
last 7 days, no words 1,008 500 1.0 ms
first index build 11 s (10.9 – 11.9 s)
index size on disk 225 MB
status check 5 ms
この表から読み取れることが 2 つあります。1 つ目は、時間が一致件数に比例しないことです。15 件の一致のほうが 2,500 件よりも長くかかりました。時間を左右するのはクエリの形(2 語のフレーズは 1 語より手間がかかる)で、返ってくるメールの量ではありません。2 つ目は、一覧に表示されるのは新しい順で最大 500 件までで、それを超える場合はその旨が表示されることです。そのため、何通一致しても結果の描画にかかる作業量には上限があります。

一度だけかかるコストはインデックスの構築で、50,000 通でおよそ 11 秒、毎秒約 4,000 通のペースで、ディスクは 225 MB です。構築はバックグラウンドで行われ、実行中も MailVault を使い続けられます。その後は、新しいメッセージと変更されたメッセージだけがインデックスされます。

1 ms と 7 ms はどんな感覚か
ミリ秒は想像しにくいので、ものさしを用意しました。60 Hz のディスプレイは 16.7 ms ごとに再描画され、ここでの最も遅い検索でも 1 回の再描画の間に終わりました。ユーザビリティ研究では 1993 年から同じ 3 つの限界が使われています。0.1 秒未満なら瞬時に感じ、1 秒までなら思考の流れが途切れず、10 秒になると注意が離れてしまいます。14 ミリ秒は「瞬時」の限界の約 7 分の 1 です。1 ms の日付フィルターは、その 100 分の 1 です。
サーバーのメール、アーカイブ、バックアップを 1 回の検索で

MailVault は 3 種類のメールを並べて保管します。サーバーから同期したメッセージ、自分でアーカイブしたメッセージ、バックアップから復元したメッセージです。どれも同じ保管庫の中のファイルになるので、すべて同じインデックスに入ります。テストでは、メールは受信トレイ、アーカイブ、送信済みの各フォルダーにあり、1 つのクエリで全体を検索しました。メッセージの出どころによって、見つかる速さは変わりません。
サーバーにしかなく、まだダウンロードしていないメールは保管庫に入っていないため、ローカルのインデックスからは見えません。そのため MailVault はサーバーにも問い合わせ、サーバーが応答する間は、インデックス済みのローカルの結果が先に表示されます。この部分はプロバイダー次第なので、数値は公表していません。Premium では、サーバーのメールボックスを 1 つではなく最大 5 つまで同時に検索できます。
外付けのバックアップドライブは、2 つ目のコールドコピーです。検索は作業用の保管庫に対して実行され、バックアップドライブにもコピーがある場合は、結果にその印が付きます。
技術: とても速く、とてもシンプルな SQL データベース
検索サーバーもクラウドサービスもありません。インデックスは保管庫の中にある 1 つの SQLite ファイルで、SQLite はおそらく世界で最も広く使われているデータベースです。MailVault は SQLite の全文検索エンジン FTS5 を trigram トークナイザーとともに使います。すべての単語が、重なり合う 3 文字の断片として保存されます。だから「voic」と入力すれば「invoice」が見つかり、ワイルドカードも単語全体の一致も要りません。アクセント記号は正規化されるので、「reunion」で「Réunion」も見つかります。単語の間にスペースを置かない日本語や中国語は、そのために作られた別のテーブルで処理されます。
速さは、3 つの素朴な判断から生まれています。
- 検索でメッセージファイルを開くことはありません。一覧に必要な情報(差出人、件名、日付、フォルダー、フラグ)は、インデックスの行にそのまま保存されています。50,000 通のテストでは、結果を組み立てる間にメールパーサーが呼ばれた回数はゼロでした。
- 1 つのファイル、1 つのプロセス。インデックスは MailVault のバックグラウンドヘルパーが所有し、一度開いたらそのまま待機させておきます。起動するものも、ネットワークで送るものもありません。
- 正本はあくまでディスク上のメールです。インデックスは派生データです。万一壊れても、MailVault は保存済みのメッセージから作り直し、メッセージ自体には一切触れません。
オフラインで動作し、何もコンピューターの外に出ません。
添付ファイルと画像 (Premium)
無料の検索では、差出人、件名、メッセージ本文が対象です。Premium では、添付ファイルの中のテキストも同じインデックス、同じ検索ボックスで検索できます。
- 添付ファイルのテキスト。PDF、Word、Excel、PowerPoint のファイルを読み取ってテキストをインデックスに加えるので、契約番号で検索すれば、その番号が PDF の中にあるメッセージが見つかります。
- macOS での画像とスキャンのテキスト。MailVault は Mac 上の Apple の Vision フレームワークで、写真、スクリーンショット、スキャンしたページの文字を認識し、インデックスに加えます。認識はデバイス上で実行されます。Windows と Linux にはこの工程はありません。
添付ファイルの中だけに存在するヒットには、クリップの印が付くので、本文が目立たないメールが表示された理由がわかります。今回のテストでは添付ファイルからの抽出時間は測っていません。抽出時間はファイル次第で、検索時ではなく、添付ファイルごとに 1 回、バックグラウンドで実行されるためです。
他のメールクライアントは検索をどう説明しているか
他のメールアプリはベンチマークしていません。以下のどのアプリも、50,000 通での検索時間は公表していません。そのため、これはストップウォッチの比較ではなく、設計の比較です。
- Apple Mail: Apple の説明によると、Spotlight の最初のインデックス作成はデータ量によって数時間、場合によっては数日かかることがあり、Mail にはインデックス作成が未完了であることを知らせる通知が表示されることがあります。
- Windows 版 Outlook は Windows Search のインデックスを使います。Microsoft の案内では、インデックス作成が終わるまで結果が不完全になることがあること、インデックスされるのはローカルにキャッシュされたメールだけであること、検索結果が多すぎると古い項目が表示されないことがあることが示されています。
- Thunderbird は独自のデータベースにグローバルインデックスを保持しています。バグトラッカーには、大きなメールボックスでインデックス作成が遅くなる問題についての長期にわたる報告があり、36,000 通に数日かかったというユーザーもいます。これらは古いハードウェアでのユーザー報告であり、今回のテストとは直接比較できません。
私たちの設計は、一般的なものとは逆です。自分で保存したコピーにインデックスを作り、それを小さな 1 つのファイルにまとめ、クエリの経路を短く保つことで、答えがミリ秒単位で返ってきます。
このテストでわからないこと
メールボックスは人工的なものです。実際のメールはもっと大きく雑多なので、本文が長い場合はインデックスも大きくなりますが、クエリが調べるのはインデックスであって、ファイルではありません。時間はウォームキャッシュでの値で、再起動後の最初の検索ではディスクからより多く読み込みます。テストの対象は件名、差出人、本文で、添付ファイルのテキストは含まれず、実行したのは 1 台のマシンです。
測定は自分で再現できます。ベンチマークは MailVault のソースツリーにある、無視指定の Rust テスト search_index_bench_50k_real_parser で、上に挙げた数値をすべて出力します。
6 年前のメールを、ミリ秒で見つけましょう。
MailVault はアーカイブのそばにプライベートな検索インデックスを持つので、50,000 通でも 500 通と同じように簡単に検索できます。無料でお使いいただけます。添付ファイルと画像の検索は Premium に含まれます。
出典: Apple サポート、Spotlight のインデックス作成、Microsoft サポート、Outlook の検索の問題、Mozilla Bugzilla 585429。ベンチマークは 2026年9月21日に測定しました。