とあるイルカのバーボンハウス

12,359 views

Published on

2013/10/25 MySQL Casual Talks #5

0 Comments
11 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
12,359
On SlideShare
0
From Embeds
0
Number of Embeds
8,994
Actions
Shares
0
Downloads
12
Comments
0
Likes
11
Embeds 0
No embeds

No notes for slide

とあるイルカのバーボンハウス

  1. 1. とあるイルカの バーボンハウス 2013/10/25 yoku0825 MySQL Casual Talks #5
  2. 2. やあ (´ ・ ω ・ `) ようこそ、バーボンハウスへ。 このDDLはサービスだから、 まず読んで落ち着いて欲しい。
  3. 3. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  4. 4. うん、「また」なんだ。済まない。 仏の顔もって言うしね、 謝って許してもらおうとも思っていない。
  5. 5. でも、このDDLを見たとき、 君は、きっと言葉では言い表せない 「ヒャッハー」みたいなものを 感じてくれたと思う。 世紀末の過ぎ去った世の中で、 そういう気持ちを忘れないで欲しい そう思って、このDDLを書いたんだ。 じゃあ、注文を聞こうか。
  6. 6. ( ゚ д ゚ ) ヒャッハー
  7. 7. 跪け! 命乞いをしろ!
  8. 8. というわけで ● ● yoku0825 とある企業のDBA ● ● ● ● オラクれない ポスグれない マイエスキューエる その正体は ● ● ● 嫁の夫 せがれの父 ぬいぐるみスキー
  9. 9. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  10. 10. ` オンラインでは INSERT が主で、 バッチで SELECT することがあります! UPDATE と DELETE は基本的に 走りません! '
  11. 11. orz ログテーブル。。 イイケドサ
  12. 12. ` 保存件数は毎月 1000 万行で、 保存期間は最低 1 年です! '
  13. 13. orz だったら型もうちょっと考えて。。
  14. 14. ` パージは月ごとのテーブルに分けて TRUNCATE しようと思うんです! '
  15. 15. Σ( ゚ д ゚ lll) 節子、それ 1 年保存やない、 11 か月保存や!
  16. 16. テーブル定義もツッコミどころ満載
  17. 17. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  18. 18. なぜサロゲートキーを SIGNED BIGINT にした
  19. 19. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  20. 20. なぜ敢えて予約語を選んだ KEY (`key`) とかギャグか
  21. 21. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  22. 22. 容量がタイトなのに 何故バイナリー文字列を CHAR 型にする
  23. 23. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  24. 24. int(1) は 1 バイト INT じゃない 1 バイト INT は TINYINT だ
  25. 25. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  26. 26. 5.5 なら DATETIME は 8 バイトだが TIMESTAMP は 4 バイトだ
  27. 27. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  28. 28. 何故その名前にしたのか 俺の目を見て言ってみろ
  29. 29. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  30. 30. 情報量が全くない名前をつけるな
  31. 31. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  32. 32. aa_id はクラスタードインデックスだから 末尾につける必要はない `3` と重複してる
  33. 33. CREATE TABLE `hogehoge`( `aa_id` bigint NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `key` varchar(64) NOT NULL, `cc_url` varchar(255) NOT NULL, `dd_json` text, `ee_flag` int(1) NOT NULL, `pp_date` datetime NOT NULL, `qq_date` datetime NOT NULL, PRIMARY KEY(`aa_id`), UNIQUE KEY `uidx_hogehoge_01`(`cc_url`), KEY `1`(`ee_flag`, `cc_url`, `aa_id`), KEY `2`(`cc_url', `ee_flag'), KEY `3`(`ee_flag`, `cc_url`), KEY `idx_hogehoge_01`(`key`), KEY `idx_hogehoge_02`(`pp_date`) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4;
  34. 34. `2` と `3` も微妙だ ORDER BY 狙いだから 重複じゃないっていうにしては cc_url はユニークキーだ
  35. 35. orz
  36. 36. 怖ろしいDDLしてるだろ。 ウソみたいだろ。 SQLレビュー通ってるんだぜ、 それで。
  37. 37. orz
  38. 38. ` じゃあどうしろと? '
  39. 39. CREATE TABLE `hogehoge`( `aa_id` int unsigned NOT NULL AUTO_INCREMENT, `bb_id` int unsigned NOT NULL, `ff_key` varbinary(64) NOT NULL, `cc_url` varbinary(255) NOT NULL, `dd_json` blob, `ee_flag` tinyint NOT NULL, `pp_date` timestamp NOT NULL, `qq_date` timestamp NOT NULL, PRIMARY KEY(`aa_id`, pp_date), UNIQUE KEY `idx_ccurl`(`cc_url`), KEY `idx_eeflag_ccurl_aaid` (`ee_flag`, `cc_url`, `aa_id`), KEY `idx_ccurl_eeflag`(`cc_url', `ee_flag'), KEY `idx_eeflag_ccurl`(`ee_flag`, `cc_url`), KEY `idx_ffkey`(`ff_key`), KEY `idx_ppdate`(`pp_date`) ) ENGINE= InnoDB ROW_FORMAT= COMPRESSED DEFAULT CHARSET= utf8mb4 PARTITION BY LIST(..) ..;
  40. 40. 容量節約第一
  41. 41. ただし binary 型は Java でフェッチすると java.lang.String じゃなくて byte[] で戻るらしい
  42. 42. ガッツで何とかしてもらった
  43. 43. LIST パーティショニングで 24 分割 { 偶数年 | 奇数年 } * 12 ヶ月
  44. 44. パーティショニング定義が超きたない
  45. 45. そんなにオーバーヘッドなかったから いいことにする
  46. 46. と、自分に言い聞かせている
  47. 47. インデックスの名前は基本、カラム名 ALTER TABLE .. DROP KEY の KEY キーワードをつけ忘れると悲惨なので 接頭辞 idx はつけることにした最近
  48. 48. mysql> explain -> SELECT * -> FROM fugafuga -> WHERE aa_id = xx -> AND bb_status = xx -> AND cc_id > xx -> AND dd_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY) -> ORDER BY aa_id descG *************************** 1. row *************************** id: 1 select_type: SIMPLE table: fugafuga type: range possible_keys: uidx_fugafuga, idx_fugafuga_01, idx_fugafuga_02, idx_fugafuga_03 key: idx_fugafuga_01 key_len: 4 ref: NULL rows: 2 Extra: Using where; Using filesort 1 row in set (0.00 sec)
  49. 49. EXPLAIN 取った時に見にくい SHOW CREATE TABLE とセットで見るけど、 10 個以上キーがあるとめげる
  50. 50. USE INDEX 書く時も、 WHERE を狙ってるのか ORDER BY を狙ってるのかよく判らない
  51. 51. mysql> explain -> SELECT * -> FROM fugafuga -> WHERE aa_id = xx -> AND bb_status = xx -> AND cc_id > xx -> AND dd_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY) -> ORDER BY aa_id descG *************************** 1. row *************************** id: 1 select_type: SIMPLE table: fugafuga type: range possible_keys: uni_aaid_eeid_dddate, idx_dddate_bbstatus_ccid, idx_aaid_bbstatus_ccid_dddate_ffid, idx_ccid_bbstatus_dddate key: idx_dddate_bbstatus_ccid key_len: 4 ref: NULL rows: 113055 Extra: Using where; Using filesort 1 row in set (0.00 sec)
  52. 52. 名前から型が推測できると更にすてき dd_date は DATETIME 型か TIMESTAMP 型だろう で、 key_len が 4 だから TIMESTAMP 型で しかも先頭の dd_date 部分しか 効いてないね RANGE スキャンだもんね
  53. 53. mysql> explain -> SELECT * -> FROM fugafuga USE INDEX(idx_aaid_bbstatus_ccid_dddate_ffid) -> WHERE aa_id = xx -> AND bb_status = xx -> AND cc_id > xx -> AND dd_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY) -> ORDER BY aa_id descG *************************** 1. row *************************** id: 1 select_type: SIMPLE table: fugafuga type: range possible_keys: uni_aaid_eeid_dddate, idx_dddate_bbstatus_ccid, idx_aaid_bbstatus_ccid_dddate_ffid, idx_ccid_bbstatus_dddate key: idx_aaid_bbstatus_ccid_dddate_ffid key_len: 5 ref: NULL rows: 509 Extra: Using where; Using filesort 1 row in set (0.00 sec)
  54. 54. どこ狙ったのかが SQL だけで伝わる アプリのコードに直接触ら ( れ ) ない わたしにとってこれ意思疎通が超捗る
  55. 55. コードだけで会話する必要はないけど、 コードで判りあうことも必要
  56. 56. とはいえ、 update_date とか フレームワークが自動で生成してるの 知りませんでした orz
  57. 57. 会話できるようになりたい orz
  58. 58. なお、このスライドは フィクションであり、 実在するDDLとは 一切関係がありません
  59. 59. とかだったら、 いいんですけどね! :)
  60. 60. ご清聴ありがとうございました

×