SQL Scale Lab

200 行で SQL を覚え、
3,200 万行でデータベースを理解する

第一部はある小さなオンラインショップのデータ(顧客 10 人、注文明細 200 行)で、SQL とデータベースの考え方を手を動かして身につける。 第二部は同じスキーマが 3,200 万行になった世界で、なぜ速いか・なぜ遅いかを実行計画で確かめる。

どのラボも書き換えて実行できる。壊しても npm run seed:basics /npm run seed で作り直せる。

まず 1 回、叩いてみる
見る場所: 結果の表。10 人の顧客

第一部 DB 基礎編

小さなオンラインショップの 200 行のデータを通じて、表計算との違いや SQL・リレーショナルデータベースの基礎を身につけます。

  1. 00 · 15 分無料
    データベースとは何か
    表計算シートの見た目から出発し、「文字列を送ると表が返ってくる」データベースの基本的な仕組みを理解します。
  2. 01 · 25 分無料
    テーブルを読む、作る
    顧客一覧テーブルを操作しながら、行・列・主キー・データ型・NULL の役割を学び、実際にテーブルを作成してデータを投入します。
  3. 02 · 30 分無料
    欲しい行だけ取り出す
    「未発送の注文を新しい順に 10 件取得する」。WHERE、ORDER BY、LIMIT の基本と、NULL がもたらす三値論理の落とし穴を体験します。
  4. 03 · 25 分無料
    数える、合計する、束ねる
    「今月の売上は?」「顧客ごとの注文数は?」。集計関数と GROUP BY の使い方、そして注文のない顧客が集計から消えてしまう問題を解決します。
  5. 04 · 35 分無料
    テーブルをつなぐ
    注文情報に顧客名を紐付ける。JOIN によってデータが増減する感覚、LEFT JOIN、中間テーブルの役割、そしてなぜテーブルを分けるのかを学びます。
  6. 05 · 25 分無料
    データを変える
    INSERT、UPDATE、DELETE の基本。WHERE 条件を書き忘れるリスク、実行前に影響行数を見積もる習慣、制約によるデータ保護を体感します。
  7. 06 · 25 分無料
    クエリの中にクエリを書く
    クエリの結果は単一の値にも、リストにも、表にもなります。IN、EXISTS、派生テーブル、WITH 句の使い分けと、NOT IN が持つ罠を解説します。
  8. 6+ · 20 分 · 補足無料
    補足: 行を潰さずに集計する
    集計しながら個別の行を残せるウィンドウ関数。ROW_NUMBER、累計値、前後の行との差分の算出方法を学びます(スキップしても第二部に進めます)。
  9. 07 · 30 分無料
    途中を見せない(トランザクション)
    「注文の作成」と「在庫の減算」をひとつの安全な処理としてまとめる。2つのセッションを動かし、コミット前の変更が他から見えない仕組みを体験します。
  10. 08 · 25 分無料
    インデックスの正体
    SHOW INDEX でインデックスの構造を直接確認し、EXPLAIN を使って「全件スキャン」と「インデックスによる高速検索」の違いを実感します。
  11. 09 · 30 分無料
    アプリケーションから使う
    データベース接続の仕組み、プレースホルダによる SQL インジェクション対策、ORM が発行する SQL と N+1 問題の正体に迫ります。

第二部 パフォーマンス編

1年後、注文明細が 3,200 万行に達したショップで鳴り響くアラート。現場で起きるリアルな障害を調査しながら、実行計画の読み方とパフォーマンス改善を学びます。

  1. 00 · 15 分無料
    1 年後のショップと、この計器盤
    3,200 万行の注文明細データを前に、4つの計器と4つのタブの役割、実行計画ツリーの見方、キャッシュの影響を把握します。
  2. 01 · 25 分無料
    フルスキャンとインデックス — 障害 1: マイページの表示に 4 秒かかる
    同じ 64 行を取得するのに、なぜ 4 秒と 0.2ms という圧倒的な差が生まれるのか。データページ、B+Tree インデックスの構造から紐解きます。
  3. 02 · 25 分有料
    実行計画を読む
    実行計画のツリーを下から上へと辿る読み方を習得。cost、rows、actual time、loops の意味と、推定と実測のズレから問題箇所を特定します。
  4. 03 · 25 分有料
    選択性 — 障害 2: インデックスを追加したらタイムアウトが増えた
    9割が同じ値を持つ列にインデックスを貼ると、なぜオプティマイザは判断を誤るのか。カーディナリティ、選択性、統計情報とヒストグラムを学びます。
  5. 04 · 30 分有料
    複合インデックスとカバリング — 障害 3: 購入履歴の月次集計が遅い
    「特定顧客の直近 30 日分」を最速で取得するインデックス設計。複合インデックスの列順序の原則と、テーブル本体を読みに行かないカバリングインデックスを体感します。
  6. 05 · 25 分有料
    InnoDB の内部構造
    テーブル本体が主キー順のクラスタインデックスとして格納される仕組み。連番と UUID で 25 倍の性能差が生じる理由やバッファプールの働きを解説します。
  7. 06 · 25 分有料
    ソートとページング — 障害 4: 注文一覧の 1,000 ページ目が開かない
    Filesort が発生する条件とメモリ溢れ、OFFSET による大量スキップの線形コスト、そして高速なキーセットページング(シーク法)への書き換えを学びます。
  8. 07 · 25 分有料
    JOIN — 障害 5: 商品別の売上画面が終わらない
    Nested loop と Hash join の動作原理。loops が意味するもの、結合キー双方のインデックスの重要性、結合順序の違いがもたらす劇的な影響を検証します。
  9. 08 · 25 分有料
    書き込みの代償と、稼働中のスキーマ変更
    インデックスを増やすと INSERT や UPDATE はどれほど遅くなるのか。INSTANT / INPLACE アルゴリズムを活用し、サービスを止めずに安全に DDL を実行する手法を学びます。
  10. 09 · 35 分有料
    ロック — 障害 6: セール開始直後に注文が失敗する
    行ロック待機、逆順ロックによるデッドロック、ネクストキーロックとギャップロックの挙動、インデックスのない更新がテーブル全体を止めてしまう怖さを体験します。
  11. 10 · 30 分有料
    同時に押し寄せるアクセス(同時実行・リソース飽和)
    同時接続数の増加とレスポンス遅延(p99 の悪化)、重いバッチが API を巻き込むノイジーネイバー問題、ホットスポット行の対策とスロークエリログの読み方を学びます。