大手IT面接MySQL頻出20問:インデックス・トランザクション・最適化を完全網羅
インデックス、トランザクション、ログ、最適化などMySQLの高頻出面接20問を網羅。各問題に出題ポイントと回答方向付きで、MySQL面接を全面的に準備できる。
背景紹介
正直に言うと、MySQLについては自分でもできる方だと思っていました。2年以上日常的にCRUDを書き、インデックスもたくさん追加してきました。しかし、大手IT企業の面接で初めて、自分の理解が浅いことに気づきました。面接官が基礎原理を深掘りすると、言葉に詰まってしまいました。その後、丸3週間かけてMySQLの高頻出題をすべて見直し、最もよく出る20問をまとめました。面接準備中の方の参考になれば幸いです。
一、インデックス(6問)
1. B+木の原理?なぜMySQLはB木ではなくB+木を使うのか?
出題ポイント:インデックスのデータ構造理解
B+木はB木の変種で、重要な違いは:すべてのデータが葉ノードに格納され、非葉ノードにはインデックスのみを格納;葉ノード同士は双方向リストで接続。MySQLがB+木を選んだ理由は3つ:第一に木の高さが低くIO回数が少ない(非葉ノードにデータを格納しないため、同じサイズのページにより多くのインデックス項目を格納可能);第二に範囲クエリの効率が高い(葉ノードリストで順次スキャン可能);第三にクエリ性能が安定(毎回葉ノードまで到達する必要があり、B木のような性能のばらつきがない)。
2. クラスタインデックスと非クラスタインデックスの違い?
出題ポイント:インデックス構成方式の理解
クラスタインデックスはInnoDBの主キーインデックスで、葉ノードに行データ全体を直接格納。データとインデックスが一体のため、1テーブルに1つしか作成できない。非クラスタインデックス(セカンダリインデックス)の葉ノードには主キー値が格納され、クエリに必要な列がインデックスに含まれていない場合、テーブル参照(主キー値でクラスタインデックスを再検索)が必要になる。カバリングインデックスが性能向上に有効なのは、テーブル参照を回避できるから。
3. カバリングインデックスとは?
出題ポイント:インデックス最適化戦略
カバリングインデックスとは、クエリに必要なすべての列がインデックスに含まれており、テーブル参照が不要な状態。例えば複合インデックス(a,b)があるテーブルでSELECT a,b FROM t WHERE a=1を実行すると、インデックスにaとbが既に含まれているため、インデックスから直接データを返せる。面接官がこの質問を好む理由は、これが実務の最も一般的な最適化手法の一つだから。以前、カバリングインデックスの追加でクエリ時間を800msから5msに削減した経験がある。
4. 最左マッチング原則とは?
出題ポイント:複合インデックスの使用ルール
複合インデックス(a,b,c)のマッチングルールは最も左の列から開始し、範囲クエリ(>、<、between、like前方一致)に遭遇するとマッチングが停止する。WHERE a=1 AND b=2 AND c>3はa、b、cの3列すべて使用できるが、WHERE a=1 AND c=3はa列のみ使用可能(b列がスキップされcも使用不可)。見落としやすい点:インデックス列の順序はWHERE句の記述順序に依存せず、オプティマイザが自動調整する。
5. インデックスが無効になるケースは?
出題ポイント:インデックス使用条件の判断
この質問は面接で必ず聞かれる!よくある無効化ケース:インデックス列での関数や演算の使用(WHERE YEAR(create_time)=2025);暗黙の型変換(varchar列をintで検索);LIKEの先頭ワイルドカード(LIKE '%abc');OR条件でインデックスなしの列が含まれる;最左マッチングを満たさない;NOT IN、NOT EXISTSの特定ケース。ByteDanceの面接では5つ以上列挙するよう求められたが、しっかり準備していたので大丈夫だった。
6. インデックス最適化の方法は?
出題ポイント:実際の最適化能力
インデックス最適化の核心:カバリングインデックスでテーブル参照を減らすことを優先;複合インデックスは最左マッチングに従い、選択性の高い列を前に配置;インデックス列での演算を避ける;EXPLAINで実行計画を分析しtypeとExtraフィールドを確認;ORDER BYやGROUP BYにもインデックスを検討。忘れてはいけないのは、インデックスは多ければ良いわけではなく、各インデックスのメンテナンスコストで書き込み性能が低下する。
二、トランザクション(5問)
7. ACIDとは?
出題ポイント:トランザクションの基本特性
原子性(Atomicity)はundo logで実現、トランザクションは全成功か全ロールバック;一貫性(Consistency)は目標であり、他の3つの特性で共同保証;隔離性(Isolation)はロックとMVCCで実現;永続性(Durability)はredo logで実現。面接官がよく掘り下げるのは:一貫性はデータベースだけで保証できるか?答えはノーで、アプリケーション層の制約も必要。例えば送金シナリオで残高がマイナスにならないことなど。
8. 4つの隔離レベル?MySQLのデフォルトは?
出題ポイント:トランザクション隔離メカニズム
Read Uncommitted(ダーティリード)、Read Committed(非再現リード)、Repeatable Read(ファントムリード)、Serializable。MySQLのデフォルトはRepeatable Read(RR)。RRレベルでは、InnoDBがMVCC+ギャップロックで大部分のファントムリード問題を解決するが、すべてではない——スナップショット読み取りではファントムリードは起きないが、現在読み取りでは起きる可能性がある。面接官が最も掘り下げたいのはこの「すべてではない」の詳細。
9. MVCCの原理?
出題ポイント:並行制御メカニズム
MVCCは隠し列(trx_id、roll_pointer)、undo logバージョンチェーン、ReadViewで実現。各行データには2つの隠し列:トランザクションIDとロールバックポインタ。ReadViewには現在アクティブなトランザクションIDリストが含まれ、バージョンチェーン上の各バージョンのトランザクションIDとReadViewを比較して可視性を判断。RCレベルは各SELECTで新しいReadViewを生成、RRレベルは最初のSELECT時のみ生成。この仕組みでRRが非再現リードを解決できる理由が本当に理解できた。
10. InnoDBのロックメカニズム?
出題ポイント:ロックの種類と使用場面
粒度別:テーブルロック、行ロック、ギャップロック、ネクストキーロック(ネクストキーロック=行ロック+ギャップロック)。モード別:共有ロック(S)、排他ロック(X)、インテンションロック。InnoDBの行ロックはインデックスに付与され、インデックスが使用されない場合、行ロックはテーブルロックに退化する。ネクストキーロックはRRレベルでファントムリードを防ぐInnoDBの鍵であり、インデックスレコードとその前のギャップをロックする。
11. デッドロックの発生原因と回避方法?
出題ポイント:デッドロック処理能力
デッドロック発生の4つの必要条件:相互排除、保持と待機、非割り込み、循環待機。InnoDBはデッドロックを検出すると、コスト最小のトランザクションを自動ロールバックする。回避方法:テーブルと行に固定順序でアクセス;大トランザクションを小トランザクションに分割;隔離レベルを下げる;適切なインデックスを追加してロック昇格を防止。以前、本番環境でデッドロックに遭遇したが、2つのトランザクションが異なる順序で同じ行を更新したことが原因で、更新順序を統一して解決した。
三、ログ(3問)
12. redo logとは?
出題ポイント:クラッシュリカバリメカニズム
redo logはInnoDBの物理ログで、「あるデータページにどのような変更を加えたか」を記録し、クラッシュリカバリで永続性を保証する。WAL(Write-Ahead Logging)戦略を採用し、先にログを書いてからディスクに書き込む。redo logは固定サイズの循環書き込みで、ib_logfile0とib_logfile1で構成。面接官が掘り下げる可能性:なぜデータファイルに直接書くのではなく、先にredo logに書くのか?redo logは順次書き込みで、データファイルのランダム書き込みよりはるかに高性能だから。
13. undo logとは?
出題ポイント:トランザクションロールバックメカニズム
undo logはデータ変更前の値を記録し、トランザクションのロールバックで原子性を保証すると同時に、MVCCバージョンチェーンの核心的な構成要素。INSERTはinsert undo logを生成(トランザクションコミット後に削除可能)、UPDATE/DELETEはupdate undo logを生成(他のトランザクションのスナップショット読み取りのために保持が必要)。これが長トランザクションがundo log膨張を引き起こし、性能に影響する理由。
14. binlogとredo logの違い?
出題ポイント:ログ体系の理解
binlogはServer層の論理ログで、すべてのDDLとDML操作を記録し、主にマスタスレーブレプリケーションとデータリカバリに使用;redo logはInnoDB層の物理ログで、ページの物理的変更を記録し、クラッシュリカバリに使用。主な違い:binlogは追記書き込み、redo logは循環書き込み;binlogには2つのフォーマット(statement/row)、redo logは物理フォーマットのみ;トランザクション実行中はredo logが継続的に書き込まれ、binlogはコミット時に一括書き込み。2相コミットはこの2つのログの一貫性を調整する仕組み。
四、最適化(3問)
15. スロークエリの最適化方法?
出題ポイント:パフォーマンスチューニング実践
第一步:スロークエリログを有効にして遅いSQLを特定;第二步:EXPLAINで実行計画を分析し、type(ALLフルテーブルスキャンを回避)、key(インデックスヒットの有無)、rows(スキャン行数)、Extra(Using filesort/Using temporaryの有無)に注目;第三歩:的確な最適化——インデックス追加、SQL記述の最適化、SELECT *の回避、大クエリの分割。以前、データ量が多い場合に非常に遅いページネーションクエリを、遅延結合で最適化して3秒から50ミリ秒に削減した経験がある。
16. データベースシャーディングの方法?
出題ポイント:アーキテクチャ設計能力
垂直シャーディングはビジネスドメインごとに分割、水平シャーディングはルール(ユーザーIDのモジュロなど)で分割。テーブルシャーディングも同様。一般的なミドルウェアにShardingSphereとMyCatがある。シャーディングがもたらす問題:分散トランザクション、クロスシャードJOIN、グローバルID生成、データ移行。面接官は通常:いつシャーディングすべきか?と掘り下げる。一般的に単一テーブルが2000万行を超えるか、データファイルが20GBを超えたら検討すべき。しかしシャーディングは最後の手段であり、まずインデックス最適化、読み書き分離、キャッシュを試すべき。
17. 読み書き分離の方法?
出題ポイント:アーキテクチャソリューション設計
マスタスレーブレプリケーションに基づいて実現——マスタが書き込みを担当、スレーブが読み取りを担当。コードレベルではSpringのAbstractRoutingDataSourceやShardingSphereで動的データソース切替を実現可能。注意すべき問題:マスタスレーブ遅延による古いデータの読み取り(重要なビジネスはマスタから強制読み取り可能);トランザクション内の読み書きは同じデータソースで行う必要がある。遅延は通常ミリ秒レベルだが、金融シナリオでは許容できない場合がある。
五、その他(3問)
18. マスタスレーブレプリケーションの原理?
出題ポイント:高可用性アーキテクチャの理解
3つのスレッド:マスタのBinlog Dumpスレッド(binlogを送信)、スレーブのIOスレッド(受信してrelay logに書き込み)、スレーブのSQLスレッド(relay logを実行)。3つの同期モード:非同期レプリケーション(デフォルト、データ損失の可能性)、半同期レプリケーション(少なくとも1つのスレーブが受信を確認)、完全同期レプリケーション(全スレーブが確認、性能が低い)。面接官がよく聞く:マスタスレーブ遅延の解決方法は?答え:並列レプリケーション、半同期、ビジネス層でマスタからの強制読み取り。
19. 1つのSQLの実行フロー?
出題ポイント:MySQL全体アーキテクチャの理解
コネクタ→クエリキャッシュ(8.0で削除)→アナライザ(字句・構文解析)→オプティマイザ(実行計画の選択)→エグゼキュータ(ストレージエンジンインターフェースの呼び出し)→ストレージエンジン(データ返却)。更新ステートメントはredo logとbinlogの2相コミットも伴う:まずredo logを書く(prepare状態)→binlogを書く→redo logをコミット(commit状態)。このフロー図は10回以上書いてようやく覚えた。
20. InnoDBとMyISAMの違い?
出題ポイント:ストレージエンジンの選定
InnoDBはトランザクション、行ロック、外部キー、MVCC、クラッシュリカバリをサポート;MyISAMはトランザクションと行ロックをサポートせず、テーブルロックのみだが、一部のシナリオでSELECT性能が良く、COUNT(*)のスキャンが不要。現在は基本的にInnoDBを使用し、MySQL 5.5以降のデフォルトエンジンはInnoDB。MyISAMが使われている唯一のシナリオは、読み取り専用の設定テーブルくらいかもしれない。
心得とアドバイス
MySQL面接の準備についてのアドバイス:まず全体アーキテクチャを理解し(SQLがどう実行されるか)、次に各モジュール(インデックス、トランザクション、ログ)を深掘りし、最後にすべてを繋げる。答えを暗記するだけでは不十分で、面接官はさらに深掘りしてくる。原理を本当に理解してこそ対応できる。ソースコードの読解と実際の操作を組み合わせることをお勧めする。EXPLAINで各種SQLの実行計画を分析したり、手動でデッドロックシナリオを作成して現象を観察したりすると、これらの実践経験は面接で特に評価される。
FAQ
Q:MySQL面接にソースコードの読解は必要?
一般的には不要だが、主要なデータ構造(Buffer Pool、B+木ノード構造など)のソースコード実装を理解していると大きくプラスになる。
Q:インデックス最適化の早道は?
まずEXPLAINの出力を読めるようになり、typeとExtraフィールドを理解し、スロークエリログに沿って一つずつ最適化する。
Q:トランザクション隔離レベルの面接対策は?
RRレベルでのMVCCの実装原理と、ギャップロックがどのようにファントムリードを防ぐかを重点的に理解する。これが面接で最も高頻度の深掘りポイント。