検索関数の速度とメモリ効率:VLOOKUP・INDEX+MATCH・XLOOKUP を徹底比較

VLOOKUP・INDEX+MATCH・XLOOKUP ―― 普段「どれでも同じ」と感じている方が大半でしょう。実際、数百行〜数千行レベルの日常業務では体感差はほぼゼロです。 しかし、数万行を超えるマスタと数千行の数式を組み合わせるような場面に入ると、関数の内部構造の違いが「秒単位の速度差」や「32ビットExcelのメモリ上限突破」として突如表面化します。

この記事では、各検索関数が「何を」「どれだけ」メモリに読み込んでいるのかを軸に、速度特性とメモリ効率の本質的な違いを解説します。 さらに、ソート済みデータに対するバイナリ検索(二分探索)の劇的な高速化メカニズムと、安全に運用するためのSORT関数との組み合わせ方を詳しく掘り下げます。

🔴 この記事で最も伝えたいこと:「速度が速い関数=最適な関数」ではない
ベンチマーク上の速度だけを見ると VLOOKUP が最速ですが、32ビットExcel環境ではメモリ効率の低さが致命的なボトルネックになります。 メモリ上限(約2GB)を超えた瞬間にOSのスワップが発生し、「ベンチマークでは最速の関数が、実際の業務では最も遅い」という逆転現象が起こり得ます。 速度・メモリ効率・保守性を総合的に判断することが重要です。

【1】メモリ読み込み範囲の違い ― なぜ INDEX+MATCH はメモリ効率が良いのか

検索関数のパフォーマンス差の根本原因は、「数式が1回の計算でメモリにロードする範囲の広さ」にあります。各関数が内部で読み込む範囲を視覚化してみましょう。

各関数がメモリにロードする範囲の比較
▼ INDEX + MATCH ― 必要最小限の2列だけ
ABCDE
1社員ID氏名部署役職給与
2 1001 田中営業部主任 350,000
:検索列未読込未読込未読込取得列
=INDEX(E:E, MATCH(検索値, A:A, 0))

MATCHはA列(検索列)だけをスキャン。INDEXはE列(取得列)の該当行だけを読む。B・C・D列はメモリに一切ロードされない。

▼ VLOOKUP ― 検索列から取得列まで「全列」をロード
ABCDE
1社員ID氏名部署役職給与
2 1001 田中営業部主任 350,000
:A列〜E列の5列分すべてがメモリにロードされる
=VLOOKUP(検索値, A:E, 5, FALSE)

table_array として A:E(5列)を丸ごと指定。実際に必要なのはA列とE列だけだが、間のB・C・D列もすべてメモリに展開される。

▼ XLOOKUP ― 検索列と取得列を独立指定(INDEX+MATCHと同等)
ABCDE
2 1001 田中営業部主任 350,000
:検索配列未読込未読込未読込戻り配列
=XLOOKUP(検索値, A:A, E:E)

INDEX+MATCHと同様に、検索配列(A列)と戻り配列(E列)だけをロードする。中間列は読み込まない。

メモリ使用量のイメージ(10万行 × 取得列が検索列から5列目の場合)
INDEX + MATCH
A列(検索)
E列(取得)
未使用
VLOOKUP
A列〜E列(5列分すべて)
XLOOKUP(1列取得時)
A列(検索)
E列(取得)
未使用
結論:INDEX+MATCHとXLOOKUP(1列取得時)のメモリ使用量は同等で、ともにVLOOKUPの 2/5 程度。 VLOOKUPは「検索列〜取得列の間にある不要な列」までメモリに抱え込むため、列が離れているほど無駄が大きくなります。
32ビットExcelのメモリ上限問題 ― 「最速の関数」が「最遅」に逆転する瞬間

32ビット版Excelの仮想アドレス空間は約2GBです(LAA有効時でも最大約3〜4GB)。この空間はExcel本体・開いているブック・アドインで共有されます。

32ビットExcelのメモリ使用イメージ
メモリ上限: 2GB(全体で共有)
Excel本体
アドイン
VLOOKUPの
キャッシュ
残り僅か
↓ VLOOKUPの参照範囲が広いと…
Excel本体
アドイン
VLOOKUPキャッシュ
溢れ → スワップ発生!

VLOOKUPで広い範囲(例:A:Z の26列 × 50万行)をtable_arrayに指定すると、キャッシュだけで数百MBのメモリを消費する可能性があります。 メモリ上限に到達するとOSのスワップ(ページファイル)が発生し、ディスクI/Oが始まった瞬間に計算速度が数倍〜数十倍に劣化します。

🔴 「VLOOKUPはベンチマーク最速」が逆転するメカニズム
ベンチマークテストは通常、十分なメモリがある環境で行われます。しかし32ビットExcelの実務環境では:

INDEX+MATCHの場合:2列分(検索列+取得列)しかメモリに載せないため、 50万行×2列 ≒ 数十MB程度。メモリ上限の2GBに対して余裕があり、スワップが発生しない = 本来の速度で処理が完了する。

VLOOKUPの場合:26列分すべてをメモリに載せるため、 50万行×26列 ≒ 数百MB。他のブックやアドインと合わせてメモリ上限を突破すると、スワップが発生 = ディスクI/Oで劇的に遅くなる

結果として、ベンチマーク上は5%速いはずのVLOOKUPが、実際の業務ではINDEX+MATCHの何倍も遅くなるという逆転現象が起こります。 最悪の場合、「応答なし」でExcelがフリーズし、作業が完全に停止します。
✅ 対処法
・可能であれば64ビット版Excelに移行する(メモリ上限が事実上撤廃される)
・VLOOKUPの table_array を「業務上必要な最大列範囲」に統一しつつ、不要に広くしすぎない
INDEX+MATCH や XLOOKUP に書き換えて、参照列を必要最小限にする
・列全体参照(A:A)を避け、範囲を限定する(A2:A100000 など)
・テーブル(構造化参照)を活用する(実データ範囲だけを自動参照)
参照範囲のキャッシュと「やりがちなアンチパターン」

Excelの計算エンジンには、同じセル範囲を複数の数式が参照している場合、一度メモリに読み込んだ範囲をキャッシュして使い回すという最適化があります。 これは VLOOKUP でも INDEX+MATCH でも COUNTIF でも同様に機能します。

たとえば、1,000行の数式がすべて =VLOOKUP(…, A:E, 5, FALSE) と同じ table_array(A:E)を参照している場合、 A:E の5列分のデータは 1回だけメモリに読み込まれ、1,000個の数式すべてがそのキャッシュを共有して検索を行います。

この仕組みを理解していないと、「メモリ節約のために参照範囲を個別に狭める」という逆効果の最適化をやってしまいがちです。

VLOOKUPでの典型例

❌ やりがちなアンチパターン
B列(氏名)を取得:
=VLOOKUP(X2, A:B, 2, FALSE)

D列(役職)を取得:
=VLOOKUP(X2, A:D, 4, FALSE)

E列(給与)を取得:
=VLOOKUP(X2, A:E, 5, FALSE)

table_array が3種類 → キャッシュが3つ別々に作られる。
A列は3重にロードされ、メモリ消費が増大。
✅ 正しいアプローチ
B列(氏名)を取得:
=VLOOKUP(X2, A:E, 2, FALSE)

D列(役職)を取得:
=VLOOKUP(X2, A:E, 4, FALSE)

E列(給与)を取得:
=VLOOKUP(X2, A:E, 5, FALSE)

table_array が全て A:E → キャッシュは1つだけ。
3つの数式がすべて同じキャッシュを共有。
⚠️ 「VLOOKUPの table_array は必要な列だけに狭めるべき」は半分間違い
1種類の数式だけなら狭い方がメモリ消費が少なくなります。しかし、同じマスタ表から複数の列を取得する数式が混在する場合(実務では非常によくある)は、 範囲をバラバラにすると各範囲が別のキャッシュとなり、トータルのメモリ消費がかえって増大します。

実務での鉄則:同じマスタ表を参照するVLOOKUPは、すべて同じ table_array にそろえる。列番号だけを変える。
💡 INDEX+MATCHでも同じ原理が働く
MATCHの検索列が全数式で同じ範囲(例:A:A)を参照していれば、そのキャッシュは共有されます。
さらに、Microsoft公式ドキュメントでは「MATCHの結果を1つのセルに格納し、複数のINDEXで使い回す」テクニックが紹介されています。
H2 =MATCH(X2, A:A, 0) ← MATCHの結果を保存
I2 =INDEX(B:B, H2) ← 氏名を取得
J2 =INDEX(D:D, H2) ← 役職を取得
K2 =INDEX(E:E, H2) ← 給与を取得

COUNTIF / SUMIF でも同じ落とし穴がある

🔴 COUNTIFの「範囲バラバラ問題」は特に深刻
キャッシュの使い回しが効かなくなる問題は、VLOOKUPだけでなくCOUNTIF・SUMIF 系でもまったく同じです。 特にCOUNTIFは「重複チェック」で大量に使われることが多いため、被害が大きくなりがちです。
❌ よくある失敗:行ごとに範囲が広がるCOUNTIF
A列の重複を「自分より上の行だけ」でカウントしようとして:

A2:=COUNTIF($A$1:$A2, A2)
A3:=COUNTIF($A$1:$A3, A3)
A4:=COUNTIF($A$1:$A4, A4)

A10000:=COUNTIF($A$1:$A10000, A10000)

範囲が全行で異なる → 10,000種類の異なるキャッシュが生成される。
のべ約5,000万セルを読み込む計算になり、数分〜数十分フリーズすることもあります。
✅ 正しいアプローチ:全行で同じ範囲
範囲を固定して全数式で統一:

A2:=COUNTIF($A:$A, A2)
A3:=COUNTIF($A:$A, A3)
A4:=COUNTIF($A:$A, A4)


全数式が同じ $A:$A → キャッシュは1つだけ。
SUM・COUNTIF系は列全体参照でも「使用済み範囲」だけを効率的にスキャンするため、 固定範囲にした方がキャッシュ共有の恩恵を受けてトータルで圧倒的に高速です。

※「自分より上だけ」のカウントが必要な場合でも、全範囲でCOUNTIFしてから別の方法で重複番号を付ける方が、全体の計算時間は短くなります。
📝 キャッシュが効く条件のまとめ
複数の数式が「完全に同一の範囲」を参照していることが条件。$A$1:$A100$A$1:$A101 は別キャッシュになる。
・VLOOKUP の table_array、MATCH / COUNTIF / SUMIF の検索範囲、いずれも同じ原理。
・テーブルの構造化参照(例:テーブル1[社員ID])は自動的に全数式で同一範囲になるため、キャッシュ効率が最も高い。
「行ごとに範囲が1行ずつ広がる」パターンが最悪 ― 全数式が別のキャッシュを持つため、メモリ消費と計算時間が爆発的に増加する。

【2】速度の実測比較 ― 各関数はどれが最速なのか

「XLOOKUP は最新だから最速」と思われがちですが、実際のベンチマーク結果は意外なものです。 ただし、ベンチマーク上の速度だけで関数を選ぶのは危険です。【1】で解説したメモリ効率との兼ね合いが実務では重要になります。

⚡ Excel 2021以降で完全一致が大幅高速化
Microsoft公式ドキュメントによれば、Excel 2021(およびMicrosoft 365のバージョン1809以降)で、 未ソートデータに対するVLOOKUP・HLOOKUP・MATCHの完全一致検索が 「同じテーブル範囲から複数列を検索する場合に、従来よりはるかに高速」になったと明記されています。

これは内部的にハッシュテーブル等のキャッシュ最適化が導入されたと推測されており、 Excel 2021以降の環境では、Excel 2019以前のベンチマーク結果がそのまま当てはまらない可能性があります。

なお、Excel 2024(買い切り版)での追加の速度改善について、Microsoft公式の明確な言及は確認できていません。 Microsoft 365は常時アップデートされるため特定時点の速度特性を語りにくく、 本記事のベンチマーク議論は主にExcel 2021(買い切り版)を基準としています。
INDEX+MATCH / XLOOKUP の最大の実務メリット ― 列の挿入・削除で壊れない

速度やメモリの議論は大規模データでのみ問題になりますが、 「列の挿入・削除で数式が壊れない」という保守性の利点は、データ規模に関係なく常に効いてきます。 むしろ日常業務では、速度差よりもこちらの方がはるかに重要です。

❌ VLOOKUPの列番号問題
=VLOOKUP(A2, マスタ!A:E, 5, FALSE)

「5列目の給与」を取得。しかし、もし誰かがマスタ表のB列とC列の間に新しい列を挿入すると、 給与は6列目に移動するのに、数式の「5」は自動更新されない。

結果として、役職データが給与として返される ―― エラーにならないため間違いに気づきにくい
✅ INDEX+MATCH / XLOOKUP は列を直接指定
=INDEX(E:E, MATCH(A2, マスタ!A:A, 0))
=XLOOKUP(A2, マスタ!A:A, マスタ!E:E)

いずれも取得する列を直接セル参照で指定しているため、 列が挿入・削除されてもExcelが参照先を自動追従する。
数式を修正する必要がなく、サイレントな列ずれ事故が原理的に起こらない。
⚠️ VLOOKUPの列番号ずれは「Excelで最もよくある重大バグ」の一つ
本人が列を挿入した場合は気づけますが、共有ブックで他の人が列を追加した場合や、 数ヶ月後にマスタ表のレイアウトを変更した場合に発覚することが多く、 その間ずっと誤った値で業務が回っていたというケースは珍しくありません。
INDEX+MATCHやXLOOKUPへの移行で、この種の事故は完全に防げます。
📝 INDEX+MATCHが「全バージョン対応の王道」と呼ばれる理由
INDEX+MATCHは Excel 2007 以前から使える組み合わせで、XLOOKUPが使えない Excel 2019 以前の環境でも 「列ずれしない」「左方向にも検索できる」「メモリ効率が良い」の三拍子が揃います。 XLOOKUPが使える環境であればXLOOKUPの方が数式が短く可読性が高いですが、 どのバージョンでも安定して使えるという点でINDEX+MATCHの信頼性は揺るぎません。
単一列の完全一致検索 ― 速度の相対比較(線形検索・デフォルト設定時)
関数相対速度メモリ効率備考
VLOOKUP ★★★★★
最速クラス
⚠ 低い
広い範囲をロード
単純な構造(引数4つ)ゆえに内部最適化が効きやすい。MS公式も「INDEX+MATCHより約5%速い」と記載。ただし32bit環境ではメモリ不足で逆転リスクあり。列ずれ問題もある。
INDEX + MATCH ★★★★☆
VLOOKUPの約5%低速
✅ 高い
最小限の列のみ
2つの関数の組み合わせによるオーバーヘッドが若干存在。メモリ効率の高さから32bit環境ではスワップを回避でき、実質最速になるケースも。列ずれが起きないのが最大の強み。
XLOOKUP ★★★☆☆
VLOOKUPより約30〜40%低速
✅ 高い
最小限の列のみ
機能が豊富な分(6引数の解釈・スピル対応等)、内部処理が複雑。1列取得ではVLOOKUPやINDEX+MATCHに劣る傾向。列ずれが起きない。
LOOKUP ★★★★★
最速候補
✅ 高い 最もシンプルな構造。ソート済み・近似一致のみ。完全一致検索ができず用途が限られる。
なぜ XLOOKUP は単純な検索で VLOOKUP より遅いのか

XLOOKUPは「完全一致がデフォルト」「#N/A回避の引数処理」「複数列返却のスピル対応」「6つの引数の解釈」など、VLOOKUPにはない多くの内部処理を毎回実行しています。 これらの追加機能は利便性と安全性を大幅に向上させますが、「1つの列から1つの値を取るだけ」という最もシンプルなケースでは、その追加処理がそのままオーバーヘッドになります。

VLOOKUPは引数が4つだけで構造が極めて単純なため、Excelの内部計算エンジンによる最適化が効きやすいと考えられています。 同様の理由で、LOOKUP関数(引数2〜3個・ソート済みデータ前提)が最速候補とされる意見もあります。

💡 INDEX+MATCHのオーバーヘッドについて
INDEX+MATCHは「2つの関数を組み合わせている」ため、関数呼び出しのオーバーヘッドが理論上2回分発生します。 これがVLOOKUP(1関数)に対して約5%程度遅くなる原因と考えられます。
ただし、この差は10万行規模でも秒未満のレベルであり、メモリ効率・保守性(列ずれしない)・柔軟性を考慮すれば、INDEX+MATCHを選択するデメリットはほぼありません。 32ビット環境ではメモリ効率の高さがスワップ回避に直結するため、ベンチマーク上の5%の遅さは実質的に無意味です。
XLOOKUP が速度面で有利になるケース

XLOOKUPが「遅い」のは単一列の単純な完全一致検索の場合です。以下のケースでは逆にXLOOKUPが優位に立ちます。

✅ 複数列の一括返却
INDEX+MATCHで3列を取得するにはMATCHを3回実行する必要がある(MATCHの結果をセルに保存して使い回す手もあるが、セルを1つ消費する)。 XLOOKUPは1回の検索で3列をスピル返却できるため、取得列が増えるほどXLOOKUPの効率が勝る
✅ バイナリ検索モード ― XLOOKUP最大の速度アドバンテージ
ソート済みデータに対してXLOOKUPの第6引数=2を使うと、完全一致のまま二分探索が可能。 VLOOKUPのバイナリ検索(第4引数=TRUE)は近似一致になってしまうため、この組み合わせはXLOOKUP独自の強み。

SORT関数(Excel 2021以降)の登場により、「ソート順を関数が常に保証する」環境が整ったことで、 バイナリ検索の前提条件(昇順ソート済み)を安全かつ自動的に満たせるようになりました。 つまり「SORT関数 + XLOOKUPバイナリ検索」は、同時期に揃った2つの新機能が組み合わさって初めて実用的になった最強コンビです。
✅ IFERROR が不要
VLOOKUPで #N/A 回避のために IFERROR で包むと、「まず VLOOKUP を計算 → エラーなら再度評価」という二重計算が発生することがある。 XLOOKUPの第4引数は内部処理で完結するため、この無駄がない。
ダブルVLOOKUPテクニックはもう不要 ― XLOOKUPバイナリ検索で完全に代替できる

XLOOKUPが登場する以前、VLOOKUPで「高速かつ安全な完全一致」を実現するためにはダブルVLOOKUPという裏技が広く使われていました。

/* 旧来のダブルVLOOKUPテクニック */
=IF(VLOOKUP(A2, D:E, 1, TRUE)=A2, VLOOKUP(A2, D:E, 2, TRUE), "未登録")

1本目のVLOOKUP:近似一致(TRUE)で高速にバイナリ検索し、D列(検索列自身)を返す。
IF文:返ってきた値がA2と一致するか検証(=完全一致かチェック)。
2本目のVLOOKUP:一致していれば再度近似一致で目的の列(E列)を取得。不一致なら"未登録"。

⚠️ なぜこんな回りくどいことをしていたのか
VLOOKUPの第4引数 TRUE(近似一致)はバイナリ検索で高速ですが、 探している値がデータに存在しなくても「最も近い値」を勝手に返してしまうという致命的な仕様があります。

そのため「まず近似一致で検索 → 結果が本当に一致しているか IF で検算」という2段構えが必要でした。 1万行のマスタでこのテクニックを使うと、通常の完全一致(FALSE)より最大28倍高速になるという検証結果もあります(FastExcel / Decision Models)。

しかし、この方法には多くの問題がありました:
数式が長く複雑で、VLOOKUPが2回書かれるため可読性が低い
検索値がデータの最小値より小さい場合にエラーが出るため、追加のIFERROR処理が必要
ソートされていなければ完全に間違った結果を返すリスクがある
・後任者が仕組みを理解できず属人化しやすい
✅ XLOOKUPバイナリ検索なら、これが1行で済む
=XLOOKUP(A2, D:D, E:E, "未登録", 0, 2)
完全一致(第5引数=0)とバイナリ検索(第6引数=2)を同時指定 ― ダブルVLOOKUPの2段構えが不要
・見つからなければ第4引数("未登録")を返す ― IFもIFERRORも不要
・数式が短く、意図が明確で保守しやすい

さらにSORT関数と組み合わせれば、ソート前提の心配も完全に解消されます。 ダブルVLOOKUPテクニックを覚える必要は、もうありません。
💬 補足:近似一致(TRUE)自体を「なんとなく怖い」と避けてきた方へ
VLOOKUPの近似一致(TRUE)が高速なのは理屈としてわかっていても、 「万が一ソートが崩れていたら」「意図しない値が返ったら」という不安から、あえて使わずに完全一致(FALSE)で通してきたという方は非常に多いはずです。 実際、近似一致の「勝手に最近傍の値を返す」仕様はサイレントに間違った結果を返すため、 業務上のリスクを考えれば慎重な判断として正しいものでした。

XLOOKUPのバイナリ検索は「完全一致」が前提であり、見つからなければ明示的に第4引数の値を返します。 この「高速」と「安全」の両立こそが、VLOOKUPの近似一致が抱えていた根本的な不安を解消した点であり、 XLOOKUPの速度面における最大の進化と言えます。

【3】ベンチマーク参考値 ― 海外検証サイトのデータから

以下は海外の著名なExcel検証サイト(Ablebits.com)が公開しているベンチマーク結果です。 環境依存が大きいため、絶対値ではなく関数間の相対的な速度差を読み取ることが重要です。 また、これはメモリが十分にある環境での計測であり、32ビット環境のメモリ制約は反映されていない点に注意してください。

Ablebits.com のベンチマーク(50万行メイン×500行マスタ・32bit Excel環境)
関数範囲指定列全体参照テーブル参照動的配列
VLOOKUP 6.6秒14.2秒2.3秒1.8秒
INDEX+MATCH 8.9秒17.7秒2.6秒4.4秒
XLOOKUP 11.2秒24.1秒3.3秒7.3秒
注目ポイント:
テーブル参照が全方式で最速。構造化参照は実データ範囲だけを自動参照するため、列全体参照の無駄がなく劇的に高速。
・列全体参照(D:D)は範囲指定の2倍以上遅い。104万行分をスキャンするため。
⚠️ このベンチマークの限界
マスタが500行と比較的小さいため、VLOOKUPの table_array が広くてもメモリ上限に達しにくい条件です。 実務でマスタが数万行〜数十万行になると、VLOOKUPのメモリ消費が問題化し、特に32ビット環境ではスワップにより速度が逆転する可能性があります。 ベンチマーク結果はあくまで「メモリが十分にある理想的な条件」での参考値として捉えてください。

【4】正直、通常の業務では気にするレベルではない

ここまで詳細に速度差を解説しておいて矛盾するようですが、大多数の実務シーンでは関数の速度差を体感することはありません。

マスタ数千行・数式数百行というレベルでは、VLOOKUP・INDEX+MATCH・XLOOKUPのいずれも一瞬で計算が完了します。 上記のベンチマークは「50万行×50万数式」のような極端な条件で初めて顕在化する差であり、日常業務で関数選択の判断基準にすべきは速度よりも保守性・可読性・メモリ効率です。

✅ 日常業務での関数選択は「列ずれしないか」で決めてよい
速度差が体感ゼロのデータ規模(数千行以下)では、最も重要な判断基準は保守性です。 VLOOKUPは列の挿入・削除で列番号がずれる「サイレントバグ」のリスクがあるため、 INDEX+MATCH(全バージョン対応)またはXLOOKUP(2021以降)を使う方が安全です。 速度最適化が必要になるのは、以下のような条件が重なったときだけです。
⚡ 速度が問題になるのはこんな場面
・マスタが10万行を超える大規模データ
・数式が数千行以上にコピーされている
32ビットExcel環境でメモリ上限に近い(← この場合は速度より先にメモリ効率を優先すべき)
・ブック内に複数のシートで大量の検索関数が使われている
・INDIRECT や VOLATILE 関数との組み合わせで再計算が頻発する

これらの条件が重なったときに初めて、関数の選び方やバイナリ検索の導入が「秒単位の改善」として効いてきます。

【5】バイナリ検索(二分探索)はなぜ劇的に速いのか

バイナリ検索とは、ソート済みのデータを「半分に分割しながら」目的の値を絞り込むアルゴリズムです。 電話帳で名前を探すとき、最初のページから1ページずつめくるのではなく、真ん中あたりを開いて「探している名前はこれより前か後か」で判断する ―― これがバイナリ検索の発想です。

線形検索(デフォルト)の動き ― 上から順に1つずつ確認
1行目
確認
2行目
確認
3行目
確認
N行目
発見!

最悪の場合、全N行を1つずつ確認する必要がある。計算量:O(N)

バイナリ検索の動き ― 半分に分割しながら絞り込む

例:1〜16の昇順データから「11」を探す場合

1
中央値=8 → 11 > 8 なので 後半に絞る
1234 5678 9101112 13141516
2
中央値=12 → 11 < 12 なので 前半に絞る
9101112 13141516
3
中央値=10 → 11 > 10 なので 後半に絞る
9101112
4
中央値=11 → 一致! 発見!
11

16個のデータからたった 4回 の比較で発見。計算量:O(log₂ N)

データ件数ごとの最大比較回数
データ件数 (N)線形検索
(最悪 N 回)
バイナリ検索
(最悪 log₂N 回)
速度差
100100回7回約14倍速い
1,0001,000回10回約100倍速い
10,00010,000回14回約714倍速い
100,000100,000回17回約5,882倍速い
1,000,0001,000,000回20回約50,000倍速い
100万行のデータでも、バイナリ検索なら最大たった 20回 の比較で目的の値を見つけ出せます。

【6】バイナリ検索の設定方法 ― XLOOKUPの第6引数

XLOOKUPでバイナリ検索を使うには、第5引数(一致モード)を 0(完全一致)、第6引数(検索モード)を 2(昇順バイナリ)または -2(降順バイナリ)に設定します。

=XLOOKUP(A2, D:D, E:E, "未登録", 0, 2)

第5引数 0:完全一致 / 第6引数 2:バイナリ検索(昇順ソート済みデータ向け)。D列が昇順に並んでいることが絶対条件。

✅ XLOOKUPバイナリ検索の最大の強み ― 「完全一致 × 高速」の史上初の両立
VLOOKUPにも高速検索モードがありますが、それは第4引数を TRUE(近似一致)にした場合のみです。 VLOOKUPでは「完全一致」と「バイナリ検索」を同時に使うことができません。 見つからなかった場合に勝手に最近傍の値を返してしまう危険があります。

このためVLOOKUPで「高速かつ安全な完全一致」を実現するには、 「近似一致で検索→結果をIFで検算」というダブルVLOOKUP(2回のVLOOKUPを組み合わせるテクニック)が必要でした。 数式が長く複雑になり、属人化の原因にもなっていました。

XLOOKUPは「完全一致(0)× バイナリ検索(2)」を引数指定だけで両立できる唯一の関数です。 見つからなければ第4引数の値を返すため、IFもIFERRORもダブルVLOOKUPも一切不要。
さらに、SORT関数の登場により「ソート状態を関数が常に保証する」環境が整ったことで、 バイナリ検索の前提条件(昇順ソート済み)を安全に自動で満たせるようになりました。 これがXLOOKUPの速度面における最大の進化です。
🔴 バイナリ検索の絶対条件:データがソート済みであること
データがソートされていない場合、大小の判断が正しく機能せず、存在するはずの値が「見つからない」と誤判定されます。 エラーにはならず間違った値や "未登録" が返るため、サイレントな誤りが最も危険です。
🔴 見落としがちな落とし穴:空白セルやデータ型の混在もバイナリ検索を壊す
バイナリ検索が正しく動くための条件は「昇順ソート済み」だけではありません。 検索列に空白セルが1つでも含まれていると、二分探索の大小判断が狂い、存在するはずの値が「見つからない」と誤判定されることがあります。

これは空白セルに限った話ではなく、数値データの中に文字列が混在している場合や、 数値と「数値に見える文字列」(セルの表示形式は同じでも内部データ型が異なる)が混在している場合にも同じ問題が起こります。 バイナリ検索は中央値との大小比較で探索方向を決めますが、データ型が異なるセルに当たると比較が成立せず、 探索が想定外の方向に進んでしまうためです。

ソートだけでなく、空白行の除去とデータ型の統一が絶対条件です。 これが、次の【7】で解説する「SORT/SORTBY関数で作業シートに出力する」方法を強く推奨する理由の一つです。 SORT関数の出力結果には元データの空白行が含まれないため、空白行問題を自動的に解消できます。
📝 なぜ空白セルが混入するのか ― 実務でよくあるパターン
・マスタ表から行を削除したが、セルの内容だけ消して行自体は残した(見た目は空行だがセル範囲には含まれる)
・データの途中にメモや区切り用の空行を入れている
・CSVインポート時に末尾に空行が紛れ込んだ
・列全体参照(A:A)を使っているため、データ末尾より下の空白セルもすべて検索範囲に含まれる

いずれも見た目では気づきにくいため、バイナリ検索を使う場合は「ソート済みの中間テーブルをSORT関数で作り、それを参照する」方法が最も安全です。

【7】SORT / SORTBY 関数でソートを保証する ― バイナリ検索を安全に運用する方法

バイナリ検索の最大のリスクは「手動でソートするのを忘れた」「誰かがデータを追加してソート順が崩れた」「空白行が紛れ込んだ」というヒューマンエラーです。 Excel 2021以降では SORT / SORTBY 関数でこのリスクを根本的に排除できます。

パターン①:SORT で並べ直した配列に XLOOKUP を適用(小規模データ向け)
=XLOOKUP(検索値, SORT(A2:A1000), SORTBY(B2:B1000, A2:A1000), "未登録", 0, 2)

元データのソート順に関わらず、常に正しくバイナリ検索できる。

⚠️ 注意:この書き方では、XLOOKUPの数式1つごとにSORT/SORTBYが実行されます。 数式が数十行程度なら問題ありませんが、数百行以上にコピーする場合はパターン③を使ってください。
パターン②:LET + SORTBY + CHOOSECOLS で計算コストを最小化(中規模データ向け)
=LET( sorted, SORTBY(A2:C1000, A2:A1000, 1), XLOOKUP(検索値, CHOOSECOLS(sorted,1), CHOOSECOLS(sorted,2,3), "未登録", 0, 2) )

LET で一度だけソート結果を計算して再利用。計算コストを最小化。ただし数式ごとにLET内のSORTBYは実行される。

パターン③:大量データ ― 作業シートで「1回だけ」SORT ★最も実用的

大量の検索数式がある場合、パターン①②のように各数式内でSORT/SORTBYを呼ぶと、 数式の数だけSORT処理が繰り返されてしまいます。 作業シートにSORT結果をスピルで1回だけ出力し、各XLOOKUPはその結果を参照するのが最も効率的です。

/* 作業シートのA1セルに入力(1回だけ) */
=SORTBY(マスタ!A2:C500000, マスタ!A2:A500000, 1)
/* 各シートのXLOOKUP ― ソート済みスピル範囲を参照 */
=XLOOKUP(A2, 作業!A1#, CHOOSECOLS(作業!A1#, 2, 3), "未登録", 0, 2)
✅ この方法が最も実用的な3つの理由
SORT処理は1回だけ:XLOOKUPが1,000行あっても、SORTBYの計算は作業シートの更新時の1回のみ。 パターン①のようにXLOOKUP内にSORTを書くと、1,000回SOURTが走ることになる。
空白行が自動的に除去される:元のマスタデータに空白行があっても、SORTBY関数の出力には空白行が含まれないため、 バイナリ検索の「空白行で誤判定」問題が自動的に解消される。
データ型の不一致も目視確認しやすい:作業シートにソート結果が展開されるため、 「数値のはずが文字列になっている行」などの異常を発見しやすい。

SORTBYの計算は作業シートの更新時の1回だけ。XLOOKUPは整列済み・空白除去済みのデータを読むだけなので高速かつ安全。

【8】最終まとめ ― 速度・メモリ・保守性の総合判断

🔴 繰り返しになりますが:「ベンチマーク最速 ≠ 最適な関数」
32ビットExcel環境では、VLOOKUPのメモリ効率の低さが原因でスワップが発生し、 INDEX+MATCHの方が結果的に何倍も速く完了するという逆転が実際に起こり得ます。 速度だけでなく、メモリ効率・環境(32/64bit)・保守性(列ずれリスク)を総合的に判断してください。
関数選択の判断フロー
データ数千行以下?
→ Yes
どの関数でもOK
列ずれしない関数を推奨
(XLOOKUP or INDEX+MATCH)
↓ No(大量データ)
Excel 2021以降
(2021/2024/365)?
→ Yes
XLOOKUP + バイナリ検索
SORT関数で作業シートに出力して
空白除去+ソート保証
↓ No(旧バージョン)
32ビットExcel?
→ Yes
INDEX+MATCH 強く推奨
メモリ効率でスワップ回避
列ずれもしない
↓ No(64ビット)
INDEX+MATCH を推奨
速度差は僅差。列ずれしない安全性で優位
総合比較まとめ
項目VLOOKUPINDEX+MATCHXLOOKUP
(線形)
XLOOKUP
(バイナリ)
単一列の速度
(メモリ十分時)
✅ 最速クラス ✅ 僅差で2位 ⚠ やや遅い ✅ 圧倒的最速
複数列の速度 列数分の数式が必要 ⚠ MATCH×列数分 ✅ 1回で全列取得 ✅ 1回で全列取得
メモリ効率 ⚠ 不要な列も読む ✅ 最小限 ✅ 最小限 ✅ 最小限
32bit環境での
実質速度
❌ スワップで
逆転リスク大
✅ スワップ回避
= 実質最速
✅ スワップ回避 ✅ スワップ回避
キャッシュ共有 ✅ 同じtable_array
なら共有
✅ 同じ範囲
なら共有
✅ 同じ範囲
なら共有
✅ 同じ範囲
なら共有
完全一致×高速 ❌ 不可
(ダブルVLOOKUP必要)
⚠ 線形のみ ― (線形のみ) ✅ 唯一可能
列ずれ耐性 ❌ 列番号がズレる
サイレントバグの元
✅ 列を直接参照
自動追従する
✅ 列を直接参照
自動追従する
✅ 列を直接参照
自動追従する
バイナリ検索の
空白・型混在耐性
❌ 近似一致で事故 ― (バイナリなし) ― (線形のみ) ⚠ 空白・型混在で誤判定
SORT出力で回避可能
対応バージョン 全ver 全ver 2021以降 2021以降
✅ 結論:
日常業務(〜数千行):速度差は体感ゼロ。列ずれしない関数を選ぶのが最重要。XLOOKUP(2021以降)またはINDEX+MATCH(全バージョン)を推奨。
大量データ(1万行超)+ ソート可能XLOOKUP バイナリ検索 + 作業シートにSORT出力 が最速かつ最安全。SORT出力で空白行除去とソート保証を同時に達成。ダブルVLOOKUPはもう不要。
同じマスタから複数列を取得:VLOOKUPなら table_array を統一(キャッシュ共有)。XLOOKUPなら戻り配列を複数列指定で1発。INDEX+MATCHならMATCH結果をセルに保存して使い回し。
32ビット環境 + 広い参照範囲VLOOKUPのメモリ浪費でスワップが発生し、ベンチマーク最速のはずが実際には最も遅くなるリスクがある。INDEX+MATCH に書き換えてメモリ効率を最優先にすべき。
旧バージョン(2019以前):INDEX+MATCH が速度・メモリ・保守性(列ずれしない)の全方面で最も安定した選択肢。