fc2ブログ

makopi23のブログ

makopi23が日々の生活で感じたことを気ままに綴るブログです。

SQLアンチパターン読書会 「スパゲッティクエリ」に参加しました

2014/4/3(木) SQLアンチパターン読書会 「スパゲッティクエリ」に参加しました。

DoorKeeper
http://sqlap.doorkeeper.jp/events/10206

以下の書籍をターゲットとした読書会なのです。

SQLアンチパターンSQLアンチパターン
(2013/01/26)
Bill Karwin

商品詳細を見る


場所はいつもの湯島、株式会社アルティネットさんです。
いつも会場提供ありがとうございます。

参加者は11人かな。初参加はお2人です。
この日は17章「スパゲッティクエリ」がターゲットでした。
身近なネタということで、ディスカッションもとても盛り上がって楽しかったです。


■ アジェンダ
今回は私が発表当番でした。
SQLアンチパターン読書会 「スパゲッティクエリ」 from makopi 23


なんの捻りもなくてゴメンナサイ。。。
私が過去に出会ったスパゲッティクエリを最後に紹介しようと思ったんですが、探す時間が無かった。。。

あと、確認のため写経も一応やりました。そんときに使ったINSERT文を参考にアップしておきます。
sqlap_chapter17.txt


ちなみにスライドをアップする時に気づいたんですが、Railsの勉強会で発表した時のスライドのViewが36,000回を超えていてフイたw
HerokuではじめるRailsプログラミング入門 6-3節「複数モデルの連携」



■ディスカッション
今回もディスカッションしたいネタをみんなで付箋に書き出しました。
20140403_sqlap2.jpg


今回は身近なネタということで、付箋の枚数も多かったですね~
以下、ディスカッション時の個人メモ。
---

■ 17.3 アンチパターンの見つけ方
  • とりあえずDISTINCTを付けてみよう!ってのは超あるあるw
  • 3階上のフロアでは実際に繰り広げられていた。。。
  • 似たようなのに「とりあえずGroup byを付けてみよう!」ってのがある。


■ 17.5.5 SQLを用いたSQLの自動的な記述
  • ストアドプロシージャをやる時間が無い時に採用することがある。
  • 例えば、監査ログを取りながら別のSQLを流したい場合など。
  • teeコマンドで標準出力に出したINSERT文を解釈しながらSELECT文を組み立てて流すとか。


■ 17.2 アンチパターン:複雑な問題をワンステップで解決しようとする
  • 快感駆動はダメ! (1行で複雑に書いて、ちゃんと動かした自分に酔うみたいな)
  • SQL麻疹(はしか)
  • SQLを1行で書きたい、という人はコマンドラインを意識していることがある。
    • コンソールにSQLを貼り付けて実行する場合は、改行で実行されるため1ライナーで書く必要があった。
    • コンソールにSQLを貼り付けて動くことを確認してから、ソースコードへコピペする、ということをよくやる。
  • SELECT句の1カラム毎に改行する書き方もある。
    • DIFFを取る時に便利
  • 昔のC/S方式の時代は、サーバだけマッチョな性能のマシンを割り当てるのが一般的だった。
    • 複雑な処理はサーバのDB側でやらせたほうが性能的に良かった。
    • そのため、貧弱なクライアント側のアプリで処理をさせず、サーバ側で1SQLでやらせることがあった。
  • 昔はDBへのConnectが遅かった。
    • そのため、ループでConnectを複数発行するのではなく、1SQLでConnectを1回に制限させることがあった。
    • 最近はループを回してもいいから、インデックスを効かせるように書きましょう、という風潮にある。
  • 3000行のSELECT文を見たことがある。
    • 就職支援サイトだった。
    • 「女性に優しい」とか「沿線沿い」とか、あらゆる条件を考慮してDBからデータを引っ張ってくるSQLだった。
    • Where句は動的に組み立てるが、表示データを取ってくるのにそのSQLを使っていた。
  • 複雑な1ライナーSQLの悪いトコは、SQL嫌いを生むこと。


■ 17.4 アンチパターンを用いてもよい場合
  • プログラミングフレームワークに縛られて1SQLにすることはほとんど無い。
  • 帳票出力ツールは1SQLに縛られることはよくある。
    • MS ACCESSとか
    • SQL Server Reporting Servicesとか
    • SQLを書くと、ビャーっとExcelにグラフが出てくるみたいな挙動の帳票ツールの典型。


■ 駆動表
  • JOINする時は、軸足となる側のテーブルを決めましょう。
  • メインとなるレコードセットを決めて、そこから根を生やしていくイメージ。
  • OracleではNested Loopの外部に配置する表を 外部表(駆動表)、内部に配置する表を 内部表 というらしい。
  • SQLには書き順がある。
    • まずFROM句から書く。
    • FROM句にどのテーブルを指定するかが、頭の中の軸足になる。


■ ストアドプロシージャ
  • SQLが複雑になった場合はストアドプロシージャに逃げるという手もある。
  • ただ、ストアドプロシージャはテストがしづらいのが欠点である。リファクタリングも弱い。
  • データを加工する程度ならストアドでもよいが、ロジックをストアドで書きだすと手に負えなくなる。。。
  • C/Sの2層時代はサーバが強力だったのでストアドプロシージャは一般的だった。
  • 最近は高トラフィックはDBネックになるので、DB側でストアドを使うよりは、Web/APサーバ側に処理させるのが一般的。


■ テンポラリテーブル
  • SQLが複雑になった場合は、いったんテンポラリテーブルに結果を逃がすという手もある。
    • MySQLでは、CREATE TABLE文に「TEMPORARY」キーワードを付けることで一時テーブルを作成できる。
    • テンポラリテーブルはメモリにデータを置くので、接続が切れるとデータも自動的に消える。(後処理不要)
    • メモリ上なので、速度も速い。
  • MySQLのトランザクション分離レベルのデフォルトは、「Repeatable Read (RR)」である。
  • MySQLのRRとスナップショットの特徴を使い、「ザ・ワールド!」で時間を止めて細かくメンテする。
    • これ便利! by 木村さん


■ スパゲッティクエリの境目
  • 行数よりも、意図が読めないSQLがマズイ。
    • 例えばこの章の最初のSQLも、前後に説明文章があったからこそ、なんとか理解できた。。。
  • まず、結果が間違っているのは言語道断。
  • 結果は合っているけど、意図が読み取りにくいSQLが該当するかもしれない。
  • 要件を解きほぐす必要がある。
  • 出力結果に引っ張られると、スパゲッティクエリの原因になりやすい。
    • 例えば、横に長い結果を出せ、という要求に引きづられてSQLが複雑になる場合 etc
  • まず、スパゲッティになるなら最低限、コメントを書きましょう。
  • あと、エイリアスにわかりやすい名前をきちんと付けましょう。


■ 17.5.3 CASE式とSUM関数を組み合わせる
  • この章は、原書のSQLの間違いが多かった。。。
  • このCASEとSUMのSQLも、原著のSQLの結果が合わなくて、イライラして自分で書いた!(笑
  • CASEとSUMを組み合わせるこの形式は、かなり頻繁に使うがとても便利。

■ ホワイトボードまとめ

今回は @inda_re さんが後輩を1名連れてきてくださったのですが、その方がこまめにホワイトボードに纏めてくださいました。
20140403_sqlap1.jpg

これは良いですね~。毎回お願いしたいw


本日初参加の木村さん、Oracleにて奥野さん(@nippondanji)と一緒にMySQLのサポート業務をされているそうです。
ディスカッション時のお話も、MySQLの経験豊かな点が髄所に出てました。
あと、DBの書籍も執筆されているそうです。

プロになるための データベース技術入門 ~MySQLforWindows困ったときに役立つ開発・運用ガイドプロになるための データベース技術入門 ~MySQLforWindows困ったときに役立つ開発・運用ガイド
(2012/03/16)
木村 明治

商品詳細を見る

読書会の後、参加者で担担麺を食べに行ったんですが、お話も面白かったw
あと最終回の25章、執筆者の奥野さんに参加いただけるよう取り計らってくださいました。感謝!


★感想:
スパゲッティクエリは馴染みが深いテーマなので、話題もいっぱいでした。
個人的には7テーブルをJOINするSQLを実際に見たことがありますが、それが私のスパゲッティクエリな経験かなぁ。

あとデカルト積のとことか、INNER JOINをLEFT OUTER JOINに書き換えるトコなんかは、写経していろいろ動作を追わないと理解しづらいとこもありました。
やっぱ写経していろいろ弄ってみて理解するのが一番です。

あと、個人的には17.5.3のCASEとSUM関数を駆使するSQLをスラスラ書けるようになりたい。
ここは復習しておくと後々役に立ちそうだ。

みなさま、ありがとうございました~



■おまけ:過去の「SQLアンチパターン読書会」ブログ

1章:SQLアンチパターン読書会 「ジェイウォーク」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-65.html

2章:SQLアンチパターン読書会 「ナイーブツリー」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-70.html

3章:SQLアンチパターン読書会 「IDリクワイアド」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-73.html

3章:SQLアンチパターン読書会 「続・IDリクワイアド」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-77.html

4章;SQLアンチパターン読書会 「キーレスエントリー」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-84.html

5章:SQLアンチパターン読書会 「EAV(エンティティ・アトリビュート・バリュー)」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-90.html

6章:SQLアンチパターン読書会 「ポリモーフィック関連」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-94.html

7章:SQLアンチパターン読書会 「マルチカラムアトリビュート」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-97.html

8章:SQLアンチパターン読書会 「メタデータトリブル」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-105.html

9章:SQLアンチパターン読書会 「ラウンディングエラー」 に参加しました
 http://makopi23.blog.fc2.com/blog-entry-109.html

10章:SQLアンチパターン読書会 「サーティーワンフレーバー」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-115.html

11章:SQLアンチパターン読書会 「ファントムファイル」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-118.html

12章:SQLアンチパターン読書会 「インデックスショットガン」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-121.html

13章:SQLアンチパターン読書会 「フィア・オブ・ジ・アンノウン」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-128.html

14章:SQLアンチパターン読書会 「アンビギュアスグループ」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-130.html

15章:SQLアンチパターン読書会 「ランダムセレクション」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-133.html

16章:SQLアンチパターン読書会 「プアマンズ・サーチエンジン」に参加しました
 http://makopi23.blog.fc2.com/blog-entry-134.html



-->