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

60
とあるイルカの バーボンハウス 2013/10/25 yoku0825 MySQL Casual Talks #5

Upload: yoku0825

Post on 27-May-2015

5.481 views

Category:

Documents


0 download

DESCRIPTION

2013/10/25 MySQL Casual Talks #5

TRANSCRIPT

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

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

2013/10/25yoku0825

MySQL Casual Talks #5

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

やあ(´・ω・`)

ようこそ、バーボンハウスへ。このDDLはサービスだから、まず読んで落ち着いて欲しい。

Page 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;

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

うん、「また」なんだ。済まない。仏の顔もって言うしね、

謝って許してもらおうとも思っていない。

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

でも、このDDLを見たとき、君は、きっと言葉では言い表せない

「ヒャッハー」みたいなものを感じてくれたと思う。

世紀末の過ぎ去った世の中で、そういう気持ちを忘れないで欲しい

そう思って、このDDLを書いたんだ。

じゃあ、注文を聞こうか。

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

( ゚д ゚ ) ヒャッハー

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

跪け!

命乞いをしろ!

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

というわけで

● yoku0825● とある企業のDBA

● オラクれない● ポスグれない● マイエスキューエる

● その正体は● 嫁の夫● せがれの父● ぬいぐるみスキー

Page 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;

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

`オンラインではINSERTが主で、

バッチでSELECTすることがあります!

UPDATEと DELETEは基本的に

走りません!'

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

orz

ログテーブル。。

イイケドサ

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

`保存件数は毎月1000万行で、

保存期間は最低1年です!'

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

orz

だったら型もうちょっと考えて。。

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

`パージは月ごとのテーブルに分けて

TRUNCATEしようと思うんです!'

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

Σ( ゚д ゚ lll)

節子、それ1年保存やない、

11か月保存や!

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

テーブル定義もツッコミどころ満載

Page 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;

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

なぜサロゲートキーを

SIGNED BIGINTにした

Page 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;

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

なぜ敢えて予約語を選んだ

KEY (`key`)とかギャグか

Page 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;

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

容量がタイトなのに

何故バイナリー文字列をCHAR型にする

Page 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;

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

int(1)は 1バイトINTじゃない

1バイトINTは TINYINTだ

Page 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;

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

5.5ならDATETIMEは 8バイトだが

TIMESTAMPは 4バイトだ

Page 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;

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

何故その名前にしたのか

俺の目を見て言ってみろ

Page 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;

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

情報量が全くない名前をつけるな

Page 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;

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

aa_idはクラスタードインデックスだから

末尾につける必要はない

`3`と重複してる

Page 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;

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

`2`と `3`も微妙だ

ORDER BY狙いだから

重複じゃないっていうにしては

cc_urlはユニークキーだ

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

orz

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

怖ろしいDDLしてるだろ。

ウソみたいだろ。

SQLレビュー通ってるんだぜ、

それで。

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

orz

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

`じゃあどうしろと? '

Page 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= utf8mb4PARTITION BY LIST(..) ..;

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

容量節約第一

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

ただしbinary型は Javaでフェッチすると

java.lang.Stringじゃなくて

byte[]で戻るらしい

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

ガッツで何とかしてもらった

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

LISTパーティショニングで24分割

{偶数年 |奇数年 } * 12ヶ月

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

パーティショニング定義が超きたない

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

そんなにオーバーヘッドなかったから

いいことにする

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

と、自分に言い聞かせている

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

インデックスの名前は基本、カラム名

ALTER TABLE .. DROP KEYの

KEYキーワードをつけ忘れると悲惨なので

接頭辞 idxはつけることにした最近

Page 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 desc\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: fugafuga type: rangepossible_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 filesort1 row in set (0.00 sec)

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

EXPLAIN取った時に見にくい

SHOW CREATE TABLEとセットで見るけど、

10個以上キーがあるとめげる

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

USE INDEX書く時も、

WHEREを狙ってるのか

ORDER BYを狙ってるのかよく判らない

Page 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 desc\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: fugafuga type: rangepossible_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 filesort1 row in set (0.00 sec)

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

名前から型が推測できると更にすてき

dd_dateは

DATETIME型かTIMESTAMP型だろう

で、key_lenが 4だからTIMESTAMP型で

しかも先頭のdd_date部分しか

効いてないねRANGEスキャンだもんね

Page 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 desc\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: fugafuga type: rangepossible_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 filesort1 row in set (0.00 sec)

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

どこ狙ったのかがSQLだけで伝わる

アプリのコードに直接触ら(れ)ない

わたしにとってこれ意思疎通が超捗る

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

コードだけで会話する必要はないけど、

コードで判りあうことも必要

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

とはいえ、update_dateとか

フレームワークが自動で生成してるの

知りませんでしたorz

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

会話できるようになりたいorz

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

なお、このスライドは

フィクションであり、

実在するDDLとは

一切関係がありません

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

とかだったら、

いいんですけどね! :)

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

ご清聴ありがとうございました