状況
平日昼の本番 DB(MySQL)。access_logs は約 2 億行で、created_at にだけインデックスがある。障害調査のため、作業者が次を実行しようとしている。
実行前に止めるべき点は?
SELECT * FROM access_logs WHERE message LIKE '%timeout%';正答
- LIKE は大文字小文字を区別するので、Timeout が漏れる
- ORDER BY がないので、結果の並び順が保証されない
- 期間も LIMIT もなく 2 億行を全件走査し、本番 DB に重い負荷をかける
- '%timeout%' はダブルクォートで囲まないと文字列にならない
解説
先頭に % がある LIKE はインデックスを使えず、2 億行を全件走査する。昼の本番 DB で実行すると I/O と CPU を奪って本来の処理を遅くし、結果も大量でクライアントのメモリを圧迫する。created_at で障害の時間帯に絞り、LIMIT を付け、可能ならレプリカで実行する。MySQL の既定の照合順序では LIKE は大文字小文字を区別しないので 1 番目は誤り。並び順の保証は調査の目的には関係しない。
この問題を含む 危険察知 のテストを制限時間つきで解く
危険察知クイズへ