mysql

56
俺のSQLがこんなに 遅いわけがない id:paulownia twitter : @nullpon

Upload: paulowniaceae

Post on 17-May-2015

8.820 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: MySQL

俺のSQLがこんなに遅いわけがない

id:paulowniatwitter : @nullpon

Page 2: MySQL

4月

Page 3: MySQL

サイバーエージェントエンジニアブログに

投稿されたあるエントリが話題に

Page 4: MySQL

Redisそれは危険なほどの

スピード

Page 5: MySQL
Page 6: MySQL

MySQLの2倍速い!

Page 7: MySQL
Page 8: MySQL

はてなブックマークでも注目

Page 9: MySQL

注)はてブユーザのイメージ画像

Page 10: MySQL

•HASH index 使ってて range search やってるのに MySQL 遅いとか言ってて大丈夫なの?

•INDEX USING BTREE にしたらいいんじゃ

•ブックマークコメントでマサカリが飛び交っていると聞いて

•タイトルがカッコイイw

はてブのコメント

Page 11: MySQL

というわけで検証してみた

Page 12: MySQL

1. Hashインデックス意味ないの?

2. B-Treeならば速い?

3. 何故Redisは2倍も速いのか?

4. MySQLで危険なスピードに挑む

Page 13: MySQL

Hash インデックス意味ないの?

Page 14: MySQL

比較してみる

Page 15: MySQL

write read

Hashインデックス 14,016ms 755,127ms

インデックスなし 13,711ms 736,358ms

Page 16: MySQL

ほぼ同じ…

Page 17: MySQL

explainしてみる

Page 18: MySQL

explain select count(point) from ranking

where point > (select point from ranking where id = 'user3939' )\G

Page 19: MySQL

*************************** 1. row *************************** id: 1 select_type: PRIMARY table: ranking type: ALLpossible_keys: point key: NULL key_len: NULL ref: NULL rows: 100000 Extra: Using where*************************** 2. row *************************** id: 2 select_type: SUBQUERY table: ranking type: constpossible_keys: PRIMARY key: PRIMARY key_len: 14 ref: rows: 1 Extra:

Page 20: MySQL

テーブルフルスキャンしてる…

Page 21: MySQL

where句が < , > , betweenのときHashインデックスは使えません…

Page 22: MySQL

Hashインデックス意味なし!

Page 23: MySQL

B-Treeインデックスならば速い?

Page 24: MySQL

比較してみる

Page 25: MySQL

write read

B-Treeインデックス 13,734ms 1,398,129ms

インデックスなし 13,711ms 736,358ms

Page 26: MySQL

B-Tree遅ぇ

Page 27: MySQL

何故?

Page 28: MySQL

B-Treeが有効な理由

•Index Range Scan•Covering Index

Page 29: MySQL

Index Range Scan

•範囲検索を高速化する

•B-Treeインデックスはソート済み

•読み込みレコード件数が減るので高速

Page 30: MySQL

しかし

多くのレコードをreadする場合、インデックス読みの込みの分、

むしろ遅くなる。

Page 31: MySQL

Covering Index

•インデックスに格納された値のみで処理し、テーブルを読まない

•MySQL高速化の常套手段

Page 32: MySQL

しかし

MemoryエンジンではCovering Indexが使えない

Page 33: MySQL

というか、RDBのIndexは少数のレコードを高速に検索するためのものなので今回のようにテーブルのほとんどのデータを読む

場合には不向き

Page 34: MySQL

インデックスが有効なのはselect範囲がテーブルの

30%ぐらいまで

Page 35: MySQL

B-Treeインデックス意味なし!

Page 36: MySQL

何故RedisはMySQLの2倍速い?

Page 37: MySQL

読み込み件数の差で説明できる

Page 38: MySQL

ベンチマークでやってる事

•N 件のデータに対して(N > 1)

•1以上 N 以下のポイントをランダムに振り、

•M ポイントより大きいデータ件数をcountする(1 < M < N)

Page 39: MySQL

N = 100,000

Redis ソート済みセット 読み取りレコード件数(の期待値):50,000件

MySQL テーブルフルスキャン 読み取りレコード件数:100,000件

ベンチマークでやってる事

Page 40: MySQL

RedisのRead件数はMySQLの半分

Page 41: MySQL

だから2倍速い

Page 42: MySQL

④MySQLで

危険なスピードにチャレンジ

Page 43: MySQL

インデックスを使わず、Read件数を減らせれば

高速化できそうな気がする

Page 44: MySQL

そんな都合のいい方法あるの?

あります

Page 45: MySQL

パーティショニング(Partitioning)

Page 46: MySQL

pointの値でテーブルを分割し範囲内のパーティションのみ

スキャン

Page 47: MySQL

パーティションの刈り込み(Patition Pruning)

Page 48: MySQL

CREATE TABLE ranking ( id VARCHAR(12) NOT NULL, point INT NOT NULL, PRIMARY KEY (id, point) USING BTREE ) ENGINE=memoryPARTITION BY RANGE COLUMNS(point) ( PARTITION p0 VALUES LESS THAN (10000), PARTITION p1 VALUES LESS THAN (20000), PARTITION p2 VALUES LESS THAN (30000), PARTITION p3 VALUES LESS THAN (40000), PARTITION p4 VALUES LESS THAN (50000), PARTITION p5 VALUES LESS THAN (60000), PARTITION p6 VALUES LESS THAN (70000), PARTITION p7 VALUES LESS THAN (80000), PARTITION p8 VALUES LESS THAN (90000), PARTITION p9 VALUES LESS THAN MAXVALUE );

Page 49: MySQL

10のパーティションに分割平均45%のレコード読み込みを

スキップできるRedisに匹敵する速度が

出るはず!

Page 50: MySQL

実験してみた

Page 51: MySQL

MacBook AirOSX 10.7.3

Core i5 1.7GHz4GB MemRedis 2.4.4MySQL 5.5.15

Page 52: MySQL

write read

RedisSortedSet 12,483ms 460,709ms

MySQLPartition Pruning 13,841ms 598,233ms

MySQLTable Full Scan 13,711ms 736,358ms

Page 53: MySQL

orz

Page 54: MySQL

Table Full Scanより速いものの思ったほど速くならなかった→パーティション刈り込みには最適化の余地あり?

CAブログの結果と比べるとRedisはほぼ同じだが、MySQLフルスキャンがかなり速い→MySQLは環境依存が大きい?

2倍速い理由がRead件数で説明できなくなったし→てへぺろ

Page 55: MySQL

Redis速ぇ…

Page 56: MySQL

おしまい