ホームお問い合わせプロフィール未経験→就職転職合格率年収の相場ブラック企業判別定時帰りする方法

SQL実践入門──高速でわかりやすいクエリの書き方 要点メモ

2024年7月12日に投稿 → に更新 技術 アフィリエイトリンクを含みます

INの行式(row expression)

P96。ORで以下のように書く場合、

SELECT key, name, date_1, flg_1, date_2, flg_2, date_3, flg_3 FROM ThreeElements
WHERE (date_1 = '2013-11-01' AND flg_1 = 'T')
  OR (date_2 = '2013-11-01' AND flg_2 = 'T')
  OR (date_3 = '2013-11-01' AND flg_3 = 'T')

INの行式に置き換えられる

WHERE ('2013-11-01', 'T')
IN ((date_1, flg_1), (date_2, flg_2), (date_3, flg_3))

さらに、CASE式にも出来る

WHERE CASE WHEN date_1 = '2013-11-01' THEN flg_1
WHEN date_2 = '2013-11-01' THEN flg_2
WHEN date_3 = '2013-11-01' THEN flg_3
ELSE NULL END = 'T'

CASE式はSQLのあらゆるところに書けるらしい。SELECT列、WHERE条件 ORDER BY句等

DBのメモリ領域

1. データキャッシュ。MySQLでいうところのinnodb_buffer_pool_size。データの一部をメモリ上に載せておくことで高速化させる。

2. ログバッファ。MySQLでいうところのinnodb_log_buffer_size。更新系SQL実行時に更新情報を貯めるバッファー。ディスクへはまとめて反映される。

3. ワーキングメモリ。MySQLでいうところのsort_buffer_size(MySQL5.7のデフォルト値は256KB)。ソートやハッシュ処理で使う。

ワーキングメモリ

P16。ソートやハッシュが必要になったときに使用される。通常はデータキャッシュやログバッファとは別の領域として管理されていることが多い。不足した場合、ストレージが使用される(いわゆるTEMP落ち)。

データがメモリに治まっている間は非常に高速なのに、メモリから溢れた瞬間に一気に遅くなる、という極端な劣化が(突然)起きてしまう。かつ、この領域は複数のSQL分で共有して使用されるため、一つのSQL分を実行しているときはメモリ内に収まっていたのだが、複数のSQL文を同時実行した際の競合によって閾値を超えてしまって溢れてしまうという難しさがある。

→ では、どれくらいに増やそうかと考えて調べたところ、こちらの記事にて、

MySQL 8.0.12以降では段階的に必要量のバッファが割り当てられるようになってるため、sort_buffer_sizeに大きい値を設定したとしても無駄なメモリの利用を抑えられるようになっている

とのことなので、大きめに設定しておいて良さそうかなと思う。

実行計画でTEMP落ちをチェックする

P337。MySQLのExplain(実行計画)で、ExtraにUsing temporary; Using filesortと表示されたら、「ワーキングメモリ内でソート処理を完結させられないため、一時領域(ストレージ)にファイルを作ってソートを行う」という意味らしい。