Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RDBのトラブルの現場を追え! ~ 様々な現場を見る ~ / rdb-troubleshooting2

RDBのトラブルの現場を追え! ~ 様々な現場を見る ~ / rdb-troubleshooting2

soudai sone

August 30, 2019
Tweet

More Decks by soudai sone

Other Decks in Technology

Transcript

  1. 自己紹介
 曽根 壮大(34歳)
 株式会社 オミカレ 副社長 CTO
 
 そ  ね  

    たけ とも
 • 日本PostgreSQLユーザ会 勉強会分科会 担当
 • 3人の子供がいます(長女、次女、長男)
 • 技術的にはWeb/LL言語/RDBMSが好きです
 • コミュニティが好き
  2. スロークエリの現場
 
 REPLACE INTO hoge(id, name) SELECT id, name FROM

    foo AS f INNER JOIN bar AS b ON f.event_id = b.id WHERE f.id in ( SELECT max(event_id) FROM f WHERE canceled_at IS NULL GROP BY event_id, sheet_id );
  3. スロークエリの現場
 
 REPLACE INTO hoge(id, name) SELECT id, name FROM

    foo AS f INNER JOIN bar AS b ON f.event_id = b.id WHERE f.id in ( SELECT max(event_id) FROM f WHERE canceled_at IS NULL GROP BY event_id, sheet_id );
  4. スロークエリの現場
 
 REPLACE INTO hoge(id, name) SELECT id, name FROM

    foo AS f INNER JOIN bar AS b ON f.event_id = b.id WHERE f.id in ( SELECT max(event_id) FROM f WHERE canceled_at IS NULL GROP BY event_id, sheet_id ); REPLACE 構文はMySQLの独自構文

  5. スロークエリの現場
 
 REPLACE INTO hoge(id, name) SELECT id, name FROM

    foo AS f INNER JOIN bar AS b ON f.event_id = b.id WHERE f.id in ( SELECT max(event_id) FROM f WHERE canceled_at IS NULL GROP BY event_id, sheet_id ); 一般的なサブクエリ

  6. 不正データの現場
 id user_id event_id seat_id reservation_at cancel_at 1 1 1

    1 2019/08/19 09:10 null 2 1 2 1 2019/08/20 09:10 2019/08/21 09:10 3 1 2 4 2019/08/22 09:10 null 4 1 3 3 2019/08/23 09:10 null ︙ ︙ ︙ ︙ ︙ ︙
  7. 不正データの現場
 id user_id event_id seat_id reservation_at cancel_at 1 1 1

    1 2019/08/19 09:10 null 2 1 2 1 2019/08/20 09:10 2019/08/21 09:10 3 1 2 4 2019/08/22 09:10 null 4 1 3 3 2019/08/23 09:10 null ︙ ︙ ︙ ︙ ︙ ︙ 予約日時は必ず今よりも後

  8. 不正データの現場
 id user_id event_id seat_id reservation_at cancel_at 1 1 1

    1 2019/08/19 09:10 null 2 1 2 1 2019/08/20 09:10 2019/08/21 09:10 3 1 2 4 2019/08/22 09:10 null 4 1 3 3 2019/08/23 09:10 null ︙ ︙ ︙ ︙ ︙ ︙ キャンセル日時は必ず予約日時よりも後

  9. 不正データの現場
 id user_id event_id seat_id reservation_at cancel_at 1 1 2

    1 2019/08/19 09:10 null 2 1 2 1 2019/08/20 09:10 2019/08/21 09:10 3 1 2 1 2019/08/22 09:10 null 4 1 3 3 2019/08/23 09:10 null ︙ ︙ ︙ ︙ ︙ ︙
  10. 不正データの現場
 id user_id event_id seat_id reservation_at cancel_at 1 1 2

    1 2019/08/19 09:10 null 2 1 2 1 2019/08/20 09:10 2019/08/21 09:10 3 1 2 1 2019/08/22 09:10 null 4 1 3 3 2019/08/23 09:10 null ︙ ︙ ︙ ︙ ︙ ︙
  11. 不正データの現場
 id user_id event_id seat_id reservation_at cancel_at 1 1 2

    1 2019/08/19 09:10 null 2 1 2 1 2019/08/20 09:10 2019/08/21 09:10 3 1 2 1 2019/08/22 09:10 null 4 1 3 3 2019/08/23 09:10 null ︙ ︙ ︙ ︙ ︙ ︙ キャンセルされてから、次のデータが正しい

  12. 不正データの現場
 id user_id event_id seat_id reservation_at cancel_at 1 1 2

    1 2019/08/19 09:10 null 2 1 2 1 2019/08/20 09:10 2019/08/21 09:10 3 1 2 1 2019/08/22 09:10 null 4 1 3 3 2019/08/23 09:10 null ︙ ︙ ︙ ︙ ︙ ︙ キャンセルされてなかったのに次のレコードが入ってる

  13. 再掲
 id user_id event_id seat_id reservation_at cancel_at 1 1 1

    1 2019/08/19 09:10 null 2 1 2 1 2019/08/20 09:10 2019/08/21 09:10 3 1 2 4 2019/08/22 09:10 null 4 1 3 3 2019/08/23 09:10 null ︙ ︙ ︙ ︙ ︙ ︙
  14. remainsテーブルの例
 id event_id seat_id reservation_at 1 1 11049 null 2

    1 5467 null 3 1 3333 null 4 1 14 null ︙ ︙ ︙ ︙
  15. remainsテーブルの例
 id event_id seat_id reservation_at 1 1 11049 null 2

    1 5467 null 3 1 3333 null 4 1 14 null ︙ ︙ ︙ ︙ InnoDBはクラスタインデックスなので
 event_idのINDEXを利用した時
 暗黙的にPKでソートされえる

  16. remainsテーブルの例
 id event_id seat_id reservation_at 1 1 11049 null 2

    1 5467 null 3 1 3333 null 4 1 14 null ︙ ︙ ︙ ︙ つまり先頭からとってランダム!

  17. パフォーマンスチューニングの現場
 
 mysql> SELECT * FROM remains WHERE event_id =

    1; +----+----------+---------+-------------+ | id | event_id | seat_id | reserved_at | +----+----------+---------+-------------+ | 1 | 1 | 29 | NULL | | 2 | 1 | 59 | NULL | | 3 | 1 | 10029 | NULL | | 4 | 1 | 2009 | NULL | | 5 | 1 | 2345 | NULL | | 6 | 1 | 8756 | NULL | +----+----------+---------+-------------+ 6 rows in set (0.00 sec)