🎉

DBの問い合わせ処理の流れ

2025/02/22に公開

Daily Blogging63日目

クエリが実行される流れを軽く整理してみた。

全体の流れ

パーサ

クエリが問題ないか確認するよ

字句解析

受け取ったクエリをトークンと呼ばれる単位に分解していく

こういうクエリを受け取ったら、

SELECT name, age FROM users WHERE age > 30;

こんな感じに分解する。
SELECT, name, age, FROM, users, WHERE, age > 30

字句解析のルールは、./backend/parser/scan.lに定義されてる

構文解析

クエリがDBの文法的に正しいかを確認する。
構文解析が完了したら、問い合わせツリーを作成する
こんなイメージ

        SELECT
       /      \
  columns    FROM
    /  \       |
 name  age   users
          |
        WHERE
          |
        age > 30

リライタ

必要に応じて問い合わせツリーを書き換える

  • ルール定義
  • ビュー

ルール定義とは、クエリに対してルールを定義することで挙動をコントロールする仕組み
簡単に言えばクエリを書き換えるルールを設定できる。

ビューは、あくまでも仮想テーブルに過ぎず実体を持たないので、
実際にデータを取得するにはビューに対するクエリを、ビューの元々のクエリに書き換える。

例えばこういうビューがあったとして

CREATE VIEW older_users AS
SELECT name, age
FROM users
WHERE age > 30;

それに対してクエリをじっこうする

SELECT * FROM older_users;

リライタではこう変換されるよ

SELECT name, age
FROM users
WHERE age > 30;

ビューは、クエリのシンプルさを保てるというメリットがあるが変換が発生するのでパフォーマンスが落ちる。

プランナ/オプティマイザ

問い合わせツリーを基に、最適な実行計画を考える。
実行計画は2つの観点から検討される。
ここでの成果物がexplainコマンドで確認できる

データへのアクセス方法

スキャン方式の検討や、インデックスを使用するかなどを検討する。

結合方法

結合が必要な場合は、3つの方法から最適なものを選択する

  • nested loop
  • merg
  • hash

結合が3つ以上あれば、結合の順番とかも考えてくれる。

エグゼキュータ

実行計画を基に処理を行い、データを取得する

Discussion