インデックス使えてる?じぇじぇじぇ!

20

Click here to load reader

Upload: takuto-matsuu

Post on 08-May-2015

2.879 views

Category:

Technology


0 download

DESCRIPTION

qpstudyのLT発表資料です。懇親会がお通夜状態になったでござる。すみません。

TRANSCRIPT

Page 1: インデックス使えてる?じぇじぇじぇ!

matsuu / qpstudy20130728

インデックス使えてる?

じぇじぇじぇ!

Page 2: インデックス使えてる?じぇじぇじぇ!

● まつうです○ hatena tmatsuu○ twitter matsuu○ 32歳ぐらい

● インフラエンジニアだけど元プログラマ○ SQL好きです○ PostgreSQL派(だけど仕事はMySQLをよく使う)○ 仕事でチューニングやることもある

● 今日は懇親会のみ参加です○ 勉強会の内容とかぶってたらごめんなさい

● じぇじぇとか言ってるけど朝ドラ見てない○ じぇじぇはNHKの朝ドラ「あまちゃん」のネタです

自己紹介?じぇじぇ!

Page 3: インデックス使えてる?じぇじぇじぇ!

突然ですが…

Page 4: インデックス使えてる?じぇじぇじぇ!

クイズです

Page 5: インデックス使えてる?じぇじぇじぇ!

じぇじぇじぇ!

Page 6: インデックス使えてる?じぇじぇじぇ!

クイズの内容

● インデックスに関するクイズを3問だすよ○ 特に景品などは用意してません○ MySQLとPostgreSQLを想定しています

● 人の褌で相撲を取ってるよ○ 元ネタは http://use-the-index-luke.com/3-minute-test

● 社内勉強会の使い回しネタだよ○ じぇじぇじぇ!すみません

● 間違い等あれば適宜指摘して下さい○ じぇじぇじぇ!ごめんなさい

Page 7: インデックス使えてる?じぇじぇじぇ!

インデックスとは(Wikipedia引用)

http://ja.wikipedia.org/wiki/%E7%B4%A2%E5%BC%95_(%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9)

データベースの分野において、索引(さくいん)またはインデックス (英: index) は、表への処理を高速化するためのデータ構造。索引は表の中の1個以上の列を対象に作成され、ランダムな参照処理や一定の順序でのレコードへのアクセスの効率を高めることができる。

Page 8: インデックス使えてる?じぇじぇじぇ!

ざっくりとしたインデックス作成方法

CREATE INDEX インデックス名 ON テーブル名(カラム,...);

(例)2013年7月28日に作成された記事一覧を取得する

SELECT * FROM 記事 WHERE 作成日 = '2013-07-28';→作成日にインデックスを張る

CREATE INDEX 作成日idx ON 記事 (作成日);

Page 9: インデックス使えてる?じぇじぇじぇ!

クイズ その1

2012年に作成された記事一覧を取得したい

SELECT * FROM 記事 WHERE year(作成日) = 2012;次のようなインデックスを作ると効果があるか?CREATE INDEX i1 ON 記事 (作成日);

● 速くなる● 速くなるが、もっと良い方法がある● 速くならない

※PostgreSQLの場合はyear(作成日)→date_part('year', 作成日)

Page 10: インデックス使えてる?じぇじぇじぇ!

クイズ その1こたえ

2012年に作成された記事一覧を取得したい

SELECT * FROM 記事 WHERE year(作成日) = 2012;次のようなインデックスを作ると効果があるか?CREATE INDEX i1 ON 記事 (作成日);

×速くなる

×速くなるが、もっと良い方法がある

○速くならない

じぇじぇじぇ!

作成日にインデックスが張られていても、YEAR(作成日)にインデックスは使われない。

Page 11: インデックス使えてる?じぇじぇじぇ!

クイズ その1対策

● 関数にインデックスを張るCREATE INDEX i2 ON 記事 (YEAR(作成日));→MySQLではできません

● BETWEENを使う

SELECT タイトル FROM 記事 WHERE 作成日 BETWEEN '2012-01-01' AND '2012-12-31';● 作成年を用意するALTER TABLE 記事 ADD COLUMN 作成年 INTEGER;CREATE INDEX i3 ON 記事 (作成年);→記事を新規作成・更新した際に作成年のケアが必要

→冗長で美しくないけどね

Page 12: インデックス使えてる?じぇじぇじぇ!

クイズ その2

カテゴリが「仕事」の最新の記事を1件取得したいSELECT * FROM 記事 WHERE カテゴリ = '仕事' ORDER BY 作成日 DESC LIMIT 1;次のようなインデックスを作ると効果があるか?CREATE INDEX i4 ON 記事 (カテゴリ, 作成日);

● 速くなる● 速くなるが、もっと良い方法がある● 速くならない

Page 13: インデックス使えてる?じぇじぇじぇ!

クイズ その2こたえ

カテゴリが「仕事」の最新の記事を1件取得したいSELECT * FROM 記事 WHERE カテゴリ = '仕事' ORDER BY 作成日 DESC LIMIT 1;次のようなインデックスを作ると効果があるか?CREATE INDEX i4 ON 記事 (カテゴリ, 作成日);

○速くなる

×速くなるが、もっと良い方法がある

×速くならない

じぇじぇじぇ!

Page 14: インデックス使えてる?じぇじぇじぇ!

クイズ その2補足

CREATE INDEXのカラムにはカラムを逆順に並べるオプションDESCが存在する

CREATE INDEX i4 ON 記事 (カテゴリ, 作成日 DESC);

がしかし、今回のようなSQLであれば、DESCをつけてもつけなくても応答時間は変わらないORDER BYにカラムが複数あり、ソート順が異なるのであれば効果あり(例)ORDER BY 優先度 DESC, 作成日

※ちなみにMySQLではDESCをつけても無視されれ常にASC(MySQL 5.6現在)

Page 15: インデックス使えてる?じぇじぇじぇ!

クイズ その3

カテゴリと投稿者で記事を絞り込みたい1. SELECT * FROM 記事 WHERE 投稿者 = 'iara' AND カテゴリ = '勉強会';2. SELECT * FROM 記事 WHERE 投稿者 = 'matsuu';3. SELECT * FROM 記事 WHERE カテゴリ = 'エンタメ';次のようなインデックスを作ると効果があるか?CREATE INDEX i5 ON 記事 (カテゴリ, 投稿者);

● 1は速くなる?変わらない?● 2は速くなる?変わらない?● 3は速くなる?変わらない?

Page 16: インデックス使えてる?じぇじぇじぇ!

クイズ その3こたえ

カテゴリと投稿者で記事を絞り込みたい1. SELECT * FROM 記事 WHERE 投稿者 = 'iara' AND カテゴリ = '勉強会';2. SELECT * FROM 記事 WHERE 投稿者 = 'matsuu';3. SELECT * FROM 記事 WHERE カテゴリ = 'エンタメ';次のようなインデックスを作ると効果があるか?CREATE INDEX i5 ON 記事 (カテゴリ, 投稿者);

● 1は速くなる● 2は変わらない● 3は速くなる

じぇじぇじぇ!

Page 17: インデックス使えてる?じぇじぇじぇ!

クイズ その3補足

CREATE INDEX i5 ON 記事 (カテゴリ, 投稿者);インデックスのカラムの順番には意味がある● 検索条件がカテゴリ→OK● 検索条件がカテゴリと投稿者→OK● 検索条件が投稿者→NG● 検索条件がカテゴリとタイトル→カテゴリだけOK

投稿者のみの検索も行うなら以下も追加するのもアリかとCREATE INDEX i6 ON 記事 (投稿者);

インデックスマージってのも一応あるよ

Page 18: インデックス使えてる?じぇじぇじぇ!

いかがでしたか

クイズ終了

Page 19: インデックス使えてる?じぇじぇじぇ!

まとめ

● SELECTが遅いようであればインデックスを張ってみよう○ 効果があるかきちんと確認すべし○ 張りすぎはINSERT等が重くなるので注意

● まず検証環境を用意しましょう○ 応答が遅くなったりするので影響がないように○ データの内容や行数によっても変化するので本番とほ

ぼ同じデータを用意するのがいいよ

● 詳しくはUse The Index, Luke!を参照○ http://use-the-index-luke.com/○ 日本語の資料でいいのあれば教えてほしい

Page 20: インデックス使えてる?じぇじぇじぇ!

ご清聴

ありがとうございました