チューニングのはなし②

データストア

HDDというデバイス->ボトルネックになるのはシークタイム

シーク ・・・ HDDがディスクを読み出すためにヘッドを動かす処理
シークタイム ・・・ それにかかる時間

シーケンシャルアクセスするときとランダムアクセスでも、だいぶ変わるらしい。
ディスクアクセスは結局遅い!

RDBMS

RDBMSはデータストアとしては鉄板。
ACID特性をもつデータストシステムとしては未だに健在。
しかし、大規模データを扱わなければいけない中でそろそろRDBMSではパフォーマンスを出せなくなってきた。

  • > 分散KVSへの流れ

有償RDBMS

Oracleの誕生

  • >ライセンスが馬鹿高いのでスケールアウトしてもコストが低いOSSという流れ。

・スケールアップ
単体マシンの処理能力を上げること。
しかし、性能をあげるには限界がある。

・スケールアウト
要求される、処理量に応じてマシンを増やすこと。
マシンを増やすことで処理能力を増やす。

データベースのチューニングについてできることは2つしかない
「インデックス」と「メモリ」

MySQL

MySQLに出来ることは、Olacleに比べて少ない。
インデックスの仕組み
・複合インデックス
セカンダリインデックス
・PKはクラスタインデックス

インデックス

MySQLで作成可能なインデックス構造はB-Treeインデックス
・Hashインデックス

B-Treeインデックス

なにも指定しないとMySQLではB-Treeインデックスになる。

メリット
・レンジスキャンに向いてる 幅を指定するとき便利
・ORDER BY句にインデックス列がすべて含まれる場合はソート済みになっているのでソート処理がおこなわれないで済む 重いから

デメリット
更新時にホットスポットが出来やすい

InnoDBではクラスタインデックスになる
リーフノードにテーブルレコードが含まれる

Hashインデックス

インデックス対象カラムにHash関数をかけて、求められたHash値を利用して格納場所を指定する

メリット
等価検索ではB-Treeの方が速い

デメリット
レンジスキャンはできない

セカンダリインデックス

一つのテーブルには0個以上のインデックスを付与することが出来る。
プライマリーキーでないインデックスも付与することが出来るが参照のパフォーマンス派落ちる

複合インデックス

複数のカラムにまたがってインデックスをつけたものを複合インデックスと言う。
インデックスの付与順がすごく大事。

「グループid,ユーザid」と「ユーザid,グループid」という順番につけられたインデックスは別物である。

「グループid,ユーザid」はグループidでソートされてから、ユーザidでソートする。
「ユーザid,グループid」はユーザidでソートされてから、グループidでソートする。

原則、なるべく絞り込める方を前にする

インデックス作成の注意

1.カーディナリティの低いデータはインデックスをつけない
flgのようなtrue,falseの2値データしかないものはインデックスをつけても意味がない

2.インデックスを後からつけるのは負荷が高い

3.全表操作が必要になるので作成時に負荷があがる
降順インデックスはサポートされていない

キャッシュ

バッファキャッシュ
SELECTされたデータやインデックスをメモリ上にキャッシュする機能
ディスク参照をスキップする

# mysql (databasename) -u root
mysql > SHOW VARIABLES LIKE "innodb_%_size";

                                                                                        • +
Variable_name Value
                                                                                        • +
innodb_additional_mem_pool_size 1048576
innodb_buffer_pool_size 8388608
innodb_log_buffer_size 1048576
innodb_log_file_size 5242880
                                                                                        • +

4 rows in set (0.00 sec)

innodb_buffer_pool_size はデフォルトで8Mしか設定されていないのであげる。

インメモリストレージエンジン

MEMORYストレージエンジン
ディスクアクセスの部分をメモリで行う。

データの抽出

クエリキャッシュ
SQLの解析処理は重いので、そこをスキップすることが出来る

インデックス参照の掟

一つのデーブルにつき一つのインデックスしか参照されない
複合インデックスの場合、順序も重要
(A,B)という複合インデックスの場合、SELECTでBだけ等価条件をもつものはインデックスを使わない

カバリングインデックス

クエリで使用するすべての列を含む。
検索条件WHEREで使っている列もSELECT userid のように表示に使うものもすべて含んだインデックス。

LIKE検索は前方一致のみに使う

LIKE '%test' <-これは後方一致なのでインデックスが使用されない

JOINは禁止

大規模データの場合、非正規化を行ったり、AP側で処理させた方が速いケースがある