SQLクエリはどう実行される?データベースの裏側を図解


SQLクエリ実行の流れ SQL文 SELECT ... パーサー 文法チェック オプティマイザ 最適な計画を選択 実行エンジン データ取得 結果 行データ バッファプール(メモリ) キャッシュ 統計情報 高速アクセス ⚡ ストレージ(ディスク) テーブル インデックス 永続化データ 💾
SQLクエリ実行の流れ
ひよこ ひよこ
SQLでSELECTって書くと結果が返ってくるけど、中で何が起きてるの?
ペンギン先生 ペンギン先生
実は裏側では5つのステップを踏んでいるんだよ。まず「パーサー」がSQL文を読んで文法チェックをする。人間でいうと「この日本語、文法的に合ってるかな?」と確認する段階だね。
ひよこ ひよこ
文法チェックの次は何をするの?
ペンギン先生 ペンギン先生
次は「オプティマイザ」の出番。これがデータベースの頭脳とも言える部分で、「どの順番でテーブルを読むか」「インデックスを使うかフルスキャンするか」を判断するんだ。同じ結果を返すにも何通りもの方法があって、その中から最速の方法を選ぶんだよ。
ひよこ ひよこ
へぇ〜!最速の方法ってどうやって決めるの?
ペンギン先生 ペンギン先生
テーブルの行数やインデックスの種類、データの偏りなど「統計情報」を使って判断するんだ。たとえば100万行のテーブルから1件探すなら、全行スキャンよりB-Treeインデックスを使ったほうが速い、みたいな計算をしているよ。
ひよこ ひよこ
それで実際にデータを取りに行くの?
ペンギン先生 ペンギン先生
そう!オプティマイザが作った「実行計画」に従って「実行エンジン」がストレージからデータを読み出す。ディスクから読むと遅いから、よく使うデータは「バッファプール」というメモリ上のキャッシュに置いてあるんだ。
ひよこ ひよこ
JOINとかWHEREが複雑だと遅くなるのはなぜ?
ペンギン先生 ペンギン先生
JOINは複数のテーブルを組み合わせる処理だから、組み合わせ方次第で計算量が爆発するんだ。たとえばテーブルA(1万行)×テーブルB(1万行)を単純に全組み合わせすると1億回の比較になる。だからインデックスJOINアルゴリズムの選択が重要なんだよ。
ひよこ ひよこ
実行計画って確認できるの?
ペンギン先生 ペンギン先生
EXPLAINコマンドを使えば見られるよ。「EXPLAIN SELECT ...」と書くだけで、オプティマイザがどんな計画を立てたか表示される。遅いクエリのチューニングでは必須のテクニックだね。
ひよこ ひよこ
プロのエンジニアはどうやってクエリを速くしてるの?
ペンギン先生 ペンギン先生
まずEXPLAIN実行計画を見て、フルスキャンしている箇所にインデックスを追加するのが基本。あとは「必要なカラムだけSELECTする」「サブクエリJOINに書き換える」「LIMIT句で取得件数を制限する」といったテクニックがあるよ。実はオプティマイザも万能じゃなくて、ヒント句で人間が「こっちの方法を使って」と指示することもあるんだ。