SlideShare una empresa de Scribd logo
1 de 43
Descargar para leer sin conexión
MySQLアンチパターン
という名の愚痴
2017/02/01
yoku0825
MySQL Casual Talks vol.10
\こんばんは/
yoku0825@とある企業のDBA
オラクれない-
ポスグれない-
マイエスキューエる-
カジュアる-
⽣息域
Twitter: @yoku0825-
Blog: ⽇々の覚書-
MyNA ML: ⽇本MySQLユーザ会-
MySQL Casualʼs Slack: MySQL Casual-
1/42
Congrats
MySQL Casual
Talks vol.10 !!
2/42
Thank you
Yahoo Japan
Corporation for
providing space!!
3/42
At first,
4/42
カシュッ
5/42
This is
痛み⽌め
6/42
Reference, SQLアンチパターン
7/42
Reference, SQLアンチパターン
個⼈的には実務経験積んでから、「やっぱアンチパターンな
のかよ︕」って⽅が捗ると思う
若いうちは「あっこれ 進研ゼミ SQLアンチパターンで⾒た
やつだ︕」ってなっても理解が得られずに⼼が死ぬことが多
い
今頃たぶんTwitterで「ウチはそんなことしないぞ」って技術的ホワ
イト企業の戦⼠たちが #mysqlcasual つけて呟いてる からみんな参
考にしよう
-
8/42
MySQLアンチパターン
なるべくSQLアンチパターンに載っているアンチパターン以
外で
これをやると MySQLはカジュア
ルに死ぬ ものを集めてみたつもり
9/42
おしながき
まさかのtempテーブル1.
アンリーダブルSQL2.
MySQLはJOINが遅い、非正規化すれば速くなる3.
サブクエリー忌避症候群4.
みんなだいすきER図5.
200 Internal Server Error6.
ザ・オブジェクト命名規則7.
DBMS・ザ・オラクルマシン8.
ぼくのかんがえたさいきょうの⽌まらないサービス9.
詫び⽯はロックを取らない10.
野良MySQL 5.7が360⽇でパスワードエクスパイア11.
10/42
1. まさかのtempテーブル
「⼀時的に作ったテーブル」じゃなくて、「⼀時変数を格納
するためのテーブル」だった時の衝撃
「RDBってアプリからすると⼀番アクセスしやすい永続化で
きるグローバル変数」
(c) jflute-
SQLアンチパターンのEAVに⾼確率でつながる
否定はできないしそういう使い⽅も悪いもんじゃないが、同
じセリフを正規化できない⼈に⾔われると途端に時限爆弾の
気配がする
11/42
1. まさかのtempテーブル
RDBはテキストファイルやmemcachedに突っ込んだものよ
りよほど容量を⾷う
ストレージもメモリーも⾷う
何のためにそんなにゴテゴテ使うかというと、トランザクシ
ョンによるデータの保護とSQLによる範囲検索のため
「キャッシュミスヒットするグローバル変数」の想像がつか
ないなら、メモリーは⼤きめに
12/42
2. アンリーダブルSQL
select super_long_column_name a, yet_another_long_column_name
b, .. from super_long_table_name t left join more_long_long_table
_name t0 on .. where .. group by t.a, t.b order by ..
13/42
2. アンリーダブルSQL
全部⼩⽂字(または全部⼤⽂字)
1⽂字エイリアス
特に “a” とか “t” とか目grepできないよ-
EXPLAINの結果って全部エイリアスで表⽰されちゃうんだ-
よってEXPLAINの結果が非常に読みにくい、追いにくい-
14/42
2. アンリーダブルSQL
SQLキーワードは⼤⽂字、オブジェクト名は⼩⽂字で
AS を(キーワードとして⼤⽂字で)使う
⼊ってればまだそこを目安にエイリアスが探せる-
1⽂字エイリアスは使わない。せめて1単語以上
毎回⼿で打つわけじゃないんだから、多少のタイプ数増加で助かる命
がある
-
15/42
2. アンリーダブルSQL
SELECT super_long_column_name AS long_column, yet_another_long_co
lumn_name ya_long_column, .. FROM super_long_table_name AS long_t
able LEFT JOIN more_long_long_table_name AS more_long ON .. WHER
E .. GROUP BY long_table.long_column, long_table.ya_long_column O
RDER BY ..
16/42
( ´-`).oO(改⾏
⼊れないと全然綺
麗になったように
⾒えない
17/42
3. MySQLはJOINが遅い、非正規化すれば速くなる
って⾔ってる⼈のクエリーはだいたい、非正規化してもまた
しばらくたつと遅くなる
計測した結果⼀度は速くなるから「この選択肢は間違ってな
かった」って経験になる
あとこの⽂脈で「正規形」「非正規化」って⾔われるのは本
来の正規形の話ではなく単なるテーブル分割であることがま
れにだがよくある
18/42
3. MySQLはJOINが遅い、非正規化すれば速くなる
⼤概遅いのはJOINそのものでなく、 ORDER BY狙いのキー
や GROUP BY狙いのキーが上⼿く使えてないこと(あるい
は、ちゃんと波及させられていないこと)
NLJの仕組みがわかれば非正規化しなくても⾼速化できるよ
See also WHERE狙いのキー、ORDER BY狙いのキー
19/42
4. サブクエリー忌避症候群
SELECT ..
FROM user_main
WHERE user_id IN (SELECT user_id FROM black_list) AND ..
↓
SELECT ..
FROM user_main JOIN black_list USING(user_id)
WHERE ..
20/42
4. サブクエリー忌避症候群
「MySQLのサブクエリーは遅いので、JOINに書き換えまし
た︕」
わかる。でもサブクエリーの⽅がリーダブルなSQLではあるよね。
「MySQLのサブクエリーは遅いので、テンポラリーテーブルに
⼊れてキャッシャブルにします︕」
すごい。歴戦のMySQLerっぽい。
「MySQLのサブクエリーは遅いので、アプリケーション側でル
ープしてフィルタしてます︕」
( д ) ゚ ゚ ファッ!?
21/42
4. サブクエリー忌避症候群
MySQLには 遅いサブクエリー と 遅くないサブクエリー が
ある
サブクエリーなら何でもかんでも回避するってもんでもない-
キャッシャブルな(遅くない)サブクエリーは視認性を上げることも
ある
-
特にこのあたりのオプティマイザーの挙動は5.6, 5.7と良く
なって来ているので、バージョンアップするだけで桁違いの
速度が出ることが
実際この前⾒たけどびっくりした-
22/42
5. みんなだいすきER図
メンテされてないER図があるじゃろ︖
引継ぎのために今、2週間かけて現在の状態に整備するじゃ
ろ︖
「テーブル定義が更新されるたびにER図も更新するこ
と︕」ってコメントをつけるじゃろ︖
でもER図はpngだったりパワーポイントだったりするじゃ
ろ︖
pngの更新なんて⾯倒じゃろ︖
次の引継ぎの時にまた同じことが起こるんじゃ
23/42
5. みんなだいすきER図
ER図は必ずDDLから機械的に⽣成できるようにする
ぎっちりFK張る、または、1ドメイン1命名を徹底する
1ドメイン1命名っていうのは、 users.id = tweets.user_id じゃなくて
users.user_id = tweets.user_id ってカラム名をそろえること
これなら機械的にERが⽣成できる(たとえばMySQL Workbench)
-
あるいはそういうリレーションシップ(Not リレーション)を管理で
きるフレームワークもあるとかないとか
-
24/42
6. 200 Internal Server Error
return $conn->selectrow_hashref($sql, undef, @param);
my $ret;
eval
{
$ret= $conn->selectrow_hashref("SELECT COUNT(*) AS c FROM ..")-
>{c};
};
$ret= 0 if $@;
return $ret;
25/42
6. 200 Internal Server Error
エラーで結果セットが空っぽなのと、条件に1⾏もマッチし
ないのがどっちもundefとか
異常系と数値の0が区別されてないとか
画⾯には「条件にマッチする⾏はありませんでした(に
こ)」って出てきて
外形テスト通っちゃうやつな︕
26/42
6. 200 Internal Server Error
嘘だと思うだろ︖ あるんだぜ、本当に。
油断はするな、くれぐれも。
27/42
7. ザ・オブジェクト命名規則
sub main
{
my ($argv1, $argv2, @option)= @_;
my $argv3;
if (&validate($argv1, $argv2))
{
$argv3= 1;
}
}
28/42
7. ザ・オブジェクト命名規則
$argv1 は許されないのに flg1 が許される世界線
特に悲惨なのはインデックス。 idx_tablename_01 なんて何
の情報量もない
インデックス名なんて意識する必要がない︖-
EXPLAIN⾒る時とロック解析する時は必須-
DBAにもDBAなりの「リーダブル・ネーム」がある
29/42
7. ザ・オブジェクト命名規則
オブジェクト名は⼩⽂字がいい(Recollect アンリーダブル
SQL)
「英2単語以上から成る “̲” 区切りの⽂字列」がオススメ
MySQL上で “̲”, “$”, 以外の記号はクォートが必要-
⼆単語以上アンダースコアで区切った予約語なんて
“STRAIGHT̲JOIN” くらいだから予約語の⼼配もない
-
インデックスの命名は idx_col1_col2_col3 (col1, col2,
col3) がオススメ
EXPLAINした時にどのカラムをカバーしてるのかわかりやすい-
30/42
8. RDBMS・ザ・オラクルマシン
本来の 神託機械 とはちょっと違う意味で
SQLという祝詞をDBMSという祭壇に捧げれてお祈りしてい
れば、そのうち神託のように(正しい)答えが返ってくるこ
とを期待する⽅々ガイル
Oracle使いにそういう⼈が多い-
そのSQL、どんなにお祈りしてもMySQLじゃ(現実的な時間では)返
ってこないよ
-
31/42
8. RDBMS・ザ・オラクルマシン
RDBMSはあなたが開発しているのと同じ、何かの⽤途のた
めに作られた アプリケーション
似たようなサービスを開発しても会社や⼈によって実装が違
うように、同じRDBMSというくくりでも 実装によって得意
な処理と不得意な処理がそれぞれある
箸でもお好み焼きを焼けなくはないけど、できればヘラが欲しいね-
でもヘラじゃ⾖腐は⾷べにくいよねたぶん-
それぞれの特性を理解して使い分けられるようになるのが本
当のベンダーロックフリーでは
32/42
9. ぼくのかんがえたさいきょうの⽌まらないサービス
たとえばマスター昇格には必ず全ての更新が⽌まる瞬間が必
要で
たとえばロックっていう⼆重に処理したりするのを防ぐためのものと
⼀緒で
-
それを⽌めないということは、データが失われる/不整合が起きる可能
性があるってことで
-
Too many connectionsが出たようなもんだと思って数分くらい我慢
してほしい
-
不整合はサイレントに起こるので、エラーが返るよりよっぽ
どあとが⾯倒くさい
33/42
9. ぼくのかんがえたさいきょうの⽌まらないサービス
その「瞬間」をどれだけ短くするのかはこっちの腕の⾒せ所
だったりするので頑張る
データが壊れるかも知れない、書き込めないかも知れない作
業をするなら、メンテナンスを⾏う、あるいはエラーが出続
ける期間を許容するくらいの⼼の余裕は持っておいた⽅が良
いというか持ってください
34/42
10. 詫び⽯はロックを取らない
つまりはSQLアンチパターン キーレスエントリ
簡単にデッドロックの温床になるから張りたくない気持ちは
わかる
というか、正規化してるだけの分割ならPKでの結合になるから範囲は
思ったよりはひどくならないはず
-
非PKでもREAD-COMMITTEDだと幾分マシになるはず-
35/42
10. 詫び⽯はロックを取らない
事実は事実だけど、それを突き付けられるとDBAの⼼が折れ
る
今頃たぶんTwitterで「ウチはそんなことしないぞ」って技術的ホワイ
ト企業の戦⼠たちが以下略
-
FKでも綺麗に設計すれば詫び⽯なしでもいけるよ
FK綺麗に張るにはリレーショナルモデルの勉強をしましょ
う
36/42
11. 野良MySQL 5.7が360⽇でパスワードエクスパイア
ドSな 規格に縛られた腰の重いDBAに縛られずにMySQLを
使いたい︕
ドSな ⼝うるさいDBAにスキーマの⼝出しをされたくない︕
そうだ︕ ⾃分でMySQLを構築しよう︕
最新版の5.7.9(当時)や︕ (ドヤァ
37/42
11. 野良MySQL 5.7が360⽇でパスワードエクスパイア
DBAが設定を規格化してるのは管理コストの⾯だけじゃな
く 聖闘⼠は 同じ地雷を⼆度踏まない ためだったりもします
DBAはPITRやオンラインスキーマチェンジを⽇本語プロト
コルで受け付けるためのAPIみたいなもんです
バリバリ使ってください。ただしCPUは1個です。-
38/42
ボツになったネタたち
statusという名の論理削除
徹底節約︕ INT型 vs MEDIUMINT型
Too many connectionsのあとに
スレーブ1台で負荷分散するお︕
何もなかったことにする⾺⿅RDBMS(非strictモード)
誰でもroot
誰も知らないワーニング
39/42
ボツになったネタたち
油断できないテスト環境
読まれないエラーログ
腐った秘伝のタレ
リレーション IS NOT リレーションシップ
永久保管のデータ
5.0時代からのビュー嫌い
なんでも1ステートメントがクール
40/42
Questions
and/or
Suggestions?
41/42
Thank
you!!
42/42

Más contenido relacionado

La actualidad más candente

La actualidad más candente (20)

YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
YugabyteDBを使ってみよう(NewSQL/分散SQLデータベースよろず勉強会 #1 発表資料)
 
Tackling Complexity
Tackling ComplexityTackling Complexity
Tackling Complexity
 
MySQLで論理削除と正しく付き合う方法
MySQLで論理削除と正しく付き合う方法MySQLで論理削除と正しく付き合う方法
MySQLで論理削除と正しく付き合う方法
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
MySQLの文字コード事情
MySQLの文字コード事情MySQLの文字コード事情
MySQLの文字コード事情
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
 
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajpAt least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
 
45分間で「ユーザー中心のものづくり」ができるまで詰め込む
45分間で「ユーザー中心のものづくり」ができるまで詰め込む45分間で「ユーザー中心のものづくり」ができるまで詰め込む
45分間で「ユーザー中心のものづくり」ができるまで詰め込む
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
 
最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5
最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5
最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり
 
MQTTとAMQPと.NET
MQTTとAMQPと.NETMQTTとAMQPと.NET
MQTTとAMQPと.NET
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
MySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことMySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいこと
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 
PostgreSQL 15の新機能を徹底解説
PostgreSQL 15の新機能を徹底解説PostgreSQL 15の新機能を徹底解説
PostgreSQL 15の新機能を徹底解説
 
PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
 

Destacado (9)

MySQL 5.7の次のMySQL 8.0はどんなものになるだろう
MySQL 5.7の次のMySQL 8.0はどんなものになるだろうMySQL 5.7の次のMySQL 8.0はどんなものになるだろう
MySQL 5.7の次のMySQL 8.0はどんなものになるだろう
 
SQLアンチパターン読書会 4章 キーレスエンエントリ(外部キー嫌い)
SQLアンチパターン読書会 4章 キーレスエンエントリ(外部キー嫌い)SQLアンチパターン読書会 4章 キーレスエンエントリ(外部キー嫌い)
SQLアンチパターン読書会 4章 キーレスエンエントリ(外部キー嫌い)
 
Chef localmodeをためした
Chef localmodeをためしたChef localmodeをためした
Chef localmodeをためした
 
SQL 脳から見た Ruby
SQL 脳から見た RubySQL 脳から見た Ruby
SQL 脳から見た Ruby
 
ペパボ de MySQL
ペパボ de MySQLペパボ de MySQL
ペパボ de MySQL
 
MySQLerの7つ道具 plus
MySQLerの7つ道具 plusMySQLerの7つ道具 plus
MySQLerの7つ道具 plus
 
MySQL 5.7の次のMySQLは
MySQL 5.7の次のMySQLはMySQL 5.7の次のMySQLは
MySQL 5.7の次のMySQLは
 
MySQLの限界に挑戦する
MySQLの限界に挑戦するMySQLの限界に挑戦する
MySQLの限界に挑戦する
 
MySQL 8.0で憶えておいてほしいこと
MySQL 8.0で憶えておいてほしいことMySQL 8.0で憶えておいてほしいこと
MySQL 8.0で憶えておいてほしいこと
 

Similar a MySQLアンチパターン (6)

とあるイルカの近況報告
とあるイルカの近況報告とあるイルカの近況報告
とあるイルカの近況報告
 
MySQLテーブル設計入門
MySQLテーブル設計入門MySQLテーブル設計入門
MySQLテーブル設計入門
 
mikasafabric for MySQL
mikasafabric for MySQLmikasafabric for MySQL
mikasafabric for MySQL
 
MySQL Fabricでぼっこぼこにされたはなし
MySQL FabricでぼっこぼこにされたはなしMySQL Fabricでぼっこぼこにされたはなし
MySQL Fabricでぼっこぼこにされたはなし
 
データベース・リファクタリング読書会第四回オープニング
データベース・リファクタリング読書会第四回オープニングデータベース・リファクタリング読書会第四回オープニング
データベース・リファクタリング読書会第四回オープニング
 
MySQLおじさんの逆襲
MySQLおじさんの逆襲MySQLおじさんの逆襲
MySQLおじさんの逆襲
 

Más de yoku0825

MySQLステータスモニタリング
MySQLステータスモニタリングMySQLステータスモニタリング
MySQLステータスモニタリング
yoku0825
 

Más de yoku0825 (18)

逝くぞ最新版、罠の貯蔵は十分か
逝くぞ最新版、罠の貯蔵は十分か逝くぞ最新版、罠の貯蔵は十分か
逝くぞ最新版、罠の貯蔵は十分か
 
MySQLレプリケーションあれやこれや
MySQLレプリケーションあれやこれやMySQLレプリケーションあれやこれや
MySQLレプリケーションあれやこれや
 
片手間MySQLチューニング戦略
片手間MySQLチューニング戦略片手間MySQLチューニング戦略
片手間MySQLチューニング戦略
 
MySQLを割と一人で300台管理する技術
MySQLを割と一人で300台管理する技術MySQLを割と一人で300台管理する技術
MySQLを割と一人で300台管理する技術
 
MySQLステータスモニタリング
MySQLステータスモニタリングMySQLステータスモニタリング
MySQLステータスモニタリング
 
わかった気になるMySQL
わかった気になるMySQLわかった気になるMySQL
わかった気になるMySQL
 
わたしを支える技術
わたしを支える技術わたしを支える技術
わたしを支える技術
 
Dockerイメージで誰でも気軽にMroonga体験
Dockerイメージで誰でも気軽にMroonga体験Dockerイメージで誰でも気軽にMroonga体験
Dockerイメージで誰でも気軽にMroonga体験
 
MySQLerの7つ道具
MySQLerの7つ道具MySQLerの7つ道具
MySQLerの7つ道具
 
MHAの次を目指す mikasafabric for MySQL
MHAの次を目指す mikasafabric for MySQLMHAの次を目指す mikasafabric for MySQL
MHAの次を目指す mikasafabric for MySQL
 
5.7の次のMySQL
5.7の次のMySQL5.7の次のMySQL
5.7の次のMySQL
 
MySQLと正規形のはなし
MySQLと正規形のはなしMySQLと正規形のはなし
MySQLと正規形のはなし
 
地雷職人の朝は早い
地雷職人の朝は早い地雷職人の朝は早い
地雷職人の朝は早い
 
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーションイルカさんチームからゾウさんチームに教えたいMySQLレプリケーション
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション
 
紹介 of Anemometer
紹介 of Anemometer紹介 of Anemometer
紹介 of Anemometer
 
MySQL 5.7が魅せる新しい運用の形
MySQL 5.7が魅せる新しい運用の形MySQL 5.7が魅せる新しい運用の形
MySQL 5.7が魅せる新しい運用の形
 
MySQL5.7で遊んでみよう
MySQL5.7で遊んでみようMySQL5.7で遊んでみよう
MySQL5.7で遊んでみよう
 
光のMySQL 5.7
光のMySQL 5.7光のMySQL 5.7
光のMySQL 5.7
 

MySQLアンチパターン