SQL Lab

用語集

迷子になったときの戻り先。それぞれ「実物を初めて見た章」に飛べる。

データベース(DB)
表を預かり、文字列で頼まれた表を作って返し続ける相手。「表の束(lab_basics)」の意味でも使う。 第一部 0 章「実物: 見慣れた表」
SQL
DB に送る要求の文字列の書き方の決まり。SELECT / INSERT / UPDATE / DELETE などで始まる。 第一部 0 章「使い方: 頼み方は文字列」
サーバー / クライアント
常に動いていて頼まれるのを待つプログラムがサーバー、文字列を送って表を受け取る側(この画面)がクライアント。 第一部 0 章「仕組み: 相手はどこにいるのか」
接続
クライアントとサーバーの間の 1 本の線。SHOW PROCESSLIST の 1 行が接続 1 本。 第一部 0 章「仕組み: 相手はどこにいるのか」
テーブル
同じ形の行を集めた表。列に型がある。 第一部 1 章「顧客一覧の表」
主キー
行を一意に指す列。重複も NULL も不可。 第一部 1 章「id の列」
NULL
値がないことを表す印。比較すると常に不明になる。 第一部 1 章「email が空の人」
WHERE
条件に合う行だけを残す句。 第一部 2 章
ORDER BY / LIMIT
並べる / 先頭だけ切る。 第一部 2 章
集計関数
多くの行から 1 つの値を作る関数(COUNT / SUM / AVG / MIN / MAX)。 第一部 3 章
GROUP BY
同じ値の行を束にして、束ごとに集計する。 第一部 3 章「束にする」
外部キー
他のテーブルの主キーを指す列。DB に宣言すると整合性を守ってくれる。 第一部 4 章
JOIN
2 つのテーブルの行を、対応する値でつなぐ。INNER は対応がある行だけ、LEFT は左側を全部残す。 第一部 4 章
正規化
同じ事実を 2 か所に書かないようにテーブルを分けること。 第一部 4 章「なぜ分けるのか」
サブクエリ
SELECT の中に書く SELECT。値・集合・表として使える。 第一部 6 章
トランザクション
BEGIN から COMMIT までの複数の文を 1 つの操作として扱う仕組み。途中は他人に見えず、失敗すれば全部取り消される。 第一部 7 章
インデックス(索引)
列の値から行の場所を引くための、テーブルとは別の構造。 第一部 8 章 / 第二部 1 章
実行計画
DB が SQL をどういう手順で処理するかの手順書。EXPLAIN で見る。 第一部 8 章 / 第二部 2 章
オプティマイザ
SQL から実行計画を作る DB 内部の部品。統計情報で見積もる。 第二部 0 章
Table scan(フルスキャン)
テーブルの全行を端から読むこと。行数に比例して遅い。 第二部 1 章
ページ
InnoDB がデータを置く 16KB の単位。ディスク I/O とキャッシュはページ単位。 第二部 1 章「なぜ全部読むしかなかったのか」
B-tree
ページの目次の目次。キー順に並び、数段で目的の場所に着く。 第二部 1 章「木」
Cardinality
その列に何種類の値があるかの推定。行数 ÷ Cardinality が 1 値あたりのヒット数の見積もり。 第二部 1 章末
推定プラン / 実測プラン
EXPLAIN FORMAT=TREE(実行前の予定)/ EXPLAIN ANALYZE(実行後の実測付き)。 第二部 2 章
選択性
条件がテーブルの何割を返すか。低い(絞れない)列の単独インデックスは害になる。 第二部 3 章
複合インデックス
複数の列を並べたインデックス。先頭の列から順にしか使えない(左端一致)。 第二部 4 章
カバリングインデックス
必要な列がすべて入っていて、本体行を読まずに済むインデックス。 第二部 4 章
クラスタインデックス
主キーの B-tree。葉に行そのものが入っていて、テーブル本体はこれ。 第二部 5 章
バッファプール
ページをキャッシュするメモリ領域。収まらないとディスクを読む。 第二部 0 章 / 5 章
キーセットページング
OFFSET でなく「最後に見た id より後」で次ページを取る方法。深さに依らず一定。 第二部 6 章
駆動表(外側 / 内側)
ネステッドループ結合で先に読む側が外側(駆動表)、その 1 行ごとに引かれる側が内側。内側は索引で引けることが条件で、駆動表は WHERE で絞れて小さくなる側にする。 第二部 7 章「実物: 顧客 3 人の売上」/「驚き: 同じ索引、同じ答え、順番だけ違う」
ネステッドループ結合(nested loop join)
外側の表を先に読み、その 1 行ごとに内側の表を索引で引く二重ループで JOIN を実行する方法。内側ノードの loops は外側の行数になる。 第二部 7 章「実物: 顧客 3 人の売上」
ハッシュ結合(hash join)
小さい側をメモリ上のキーで引ける辞書にし、大きい側を 1 回だけ端から流して突き合わせる結合方法。結合列に索引が無いときに選ばれ、内側の loops は 1。 第二部 7 章「大きい側の結合列に索引が無いとき: ハッシュ結合」
書き込みの代償
索引を N 本張った表では 1 行の INSERT / UPDATE が N+1 本の B-tree を更新し、時間とディスクをその分余計に払うこと。 第二部 8 章「実物: 同じ 100 万行を、索引 0 本の表と 5 本の表に入れる」
DDL
CREATE / ALTER / DROP のように表の定義を変える文の総称(Data Definition Language)。 第二部 8 章「稼働中の変更: 列を足す」
ALGORITHM=INSTANT / INPLACE / COPY
ALTER の 3 方式。INSTANT は定義だけ書き換えて行を読まない(ミリ秒、行バージョンの上限 64)。INPLACE, LOCK=NONE は表をコピーせず横で索引を組み立て、その間も読み書きを通す。COPY は空の表に全行をコピーして入れ替え、終わるまで書き込みが待つ。 第二部 8 章「稼働中の変更」〜「3 つの方式」
メタデータロック(MDL)
表の定義を守るロック。全ての文が触る表の MDL を取ってから動くので、INSTANT でも走っている長い文の終了を待つ。待ちは lock_wait_timeout(既定 1 年)で決まる。 第二部 8 章「比べる: 表を丸ごとコピーする方式(COPY)」/「罠: INSTANT でも、走っている文を待つ」
行ロック(row lock)
UPDATE などが書き換えた行に付く「COMMIT か ROLLBACK まで他のトランザクションは書き換えられない」印。持つ側が GRANTED、欲しい側が WAITING で、待つのは書く側だけ。変更した行ではなく読んだ行に付く。 第二部 9 章「実物: 同じ行を 2 本の接続で減らす」
ロック待ちタイムアウト(innodb_lock_wait_timeout)
行ロックを何秒待ったら諦めて ER_LOCK_WAIT_TIMEOUT にするかの変数。サーバの既定は 50 秒。この教材では 1 文ラボ 10 秒、2 セッションラボ 8 秒、負荷ラボ 5 秒。 第二部 9 章「待ちはいつ失敗になるか」
デッドロック(deadlock)
2 つのトランザクションが互いの持つ行を待って輪になる状態。InnoDB は要求の瞬間に輪を検出し、片方をトランザクションごと ER_LOCK_DEADLOCK で巻き戻す。全員が同じ順序で行を取れば起きない。 第二部 9 章「デッドロック: 互いに待つ」
分離レベル(isolation level)
トランザクションの中で何が見えるかの約束。MySQL の既定は REPEATABLE READ で、範囲の FOR UPDATE に隙間のロックが付く。READ COMMITTED にすると付かない。 第一部 7 章末 / 第二部 9 章「隙間のロック: 存在しない行の INSERT が待つ」
ギャップロック(gap lock)
行だけでなく「その行の手前の隙間」も押さえるロック。REPEATABLE READ で範囲を FOR UPDATE(または索引のない UPDATE / DELETE)すると付き、隙間への INSERT を待たせる。data_locks では REC_NOT_GAP の付かない X として見える。 第二部 9 章「隙間のロック: 存在しない行の INSERT が待つ」
ホットロウ(hot row)
更新が集中する 1 行。行ロックで更新が 1 本ずつ直列に進むので QPS に天井(1 秒 ÷ ロックを持つ時間)があり、同時数を増やしても待ち行列だけが伸びる。 第二部 9 章「障害 6 を組み立てる」/ 10 章「ホットロウの天井」
スループット / レイテンシ
1 秒あたりに処理できた回数(throughput、負荷ラボの QPS)と、1 回の所要時間(latency、p50 / p99 / max)。 第二部 10 章「実物: 同時接続を 1 → 4 → 16 → 32 → 64 にする」
飽和(saturation)
同時数を増やしてもスループットが増えず、待ち時間だけが同時数に比例して伸びる点。コネクションプールの上限は飽和点 ÷ アプリの台数。 第二部 10 章「実物: 同時接続を 1 → 4 → 16 → 32 → 64 にする」
パーセンタイル(p50 / p99)
全実行の時間を速い順に並べ、50 % の位置の値が p50、99 % の位置の値が p99。平均は右の尻尾(たまに遅い)を隠す。 第二部 10 章「実物: 同時接続を 1 → 4 → 16 → 32 → 64 にする」
ノイジーネイバー(noisy neighbor)
CPU コア・ディスク・バッファプールを奪って、同居する速いクエリの p99 を伸ばす重いクエリ。奪い合いは双方向。 第二部 10 章「隣で集計バッチが走る」
スロークエリログ(slow query log)
long_query_time より遅かったクエリを表(mysql.slow_log)かファイルに記録するサーバーの仕組み。SET GLOBAL は新しい接続にしか効かない。直す順は合計時間順。 第二部 10 章「スロークエリログ: 遅いクエリを本番で見つける」
コネクションプール
アプリが数本の接続を張ったまま使い回す仕組み。1 台あたりの上限は DB の飽和点 ÷ 台数で、増やしても飽和の先は待ち行列になる。 第一部 9 章 / 第二部 10 章「接続の数と、実行中の数」