エンジニアブログ

エンジニアブログ

札幌MySQL勉強会に参加してきた(2)

photo.jpg onagatani 2011年08月20日

開発者向けチューニング編

宣伝 MYSQL徹底入門5.5

ディスクIO性能を常に意識する
HDDのランダムアクセス性能・・・5msとか
できるだけディスクアクセスをなくす
datetime型でなくtimestumpにするとか(容量が減る)

一部のクエリだけが問題をおこしたり
1%のクエリで全体の99%のリソースを消費したり

・大量のレコードスキャン
・個々の実行は早いが大量回数の実行
・スローログにでないので注意

長時間のロックを保持
他のものがまたされる
LockWaitTimeoutとか

調査
tcpdumpとmk-query-digest便利
基本的な所でexplain
オプティマイザが判断を誤る事もある。。
 ・特にソート
 ・・force indexでコントロール
 ・基本的には大丈夫ですが。

スレーブの性質
 スレーブはシングルスレッド
 低スペックだとレプリ遅延を招く

テンポラリテーブルとの相性
 5.1の行ベースバイナリログを検討

トランザクションを意識
BEGINからCOMMITまたはROLLBACKまでが1つのトランザクション
トランザクションの対象は同一サーバないのInnoDBのみ
 XAは安定していない
 トランザクション中にInnoDB更新、MyISAM更新、memcachedとかやってもInnoDBのみ

myslowtrancaptureで遅いトランザクションを特定する
- 実行に一定時間以上かかったトランザクションを特定
- githubにあります!

最後に応答を受け取ってからcommitするまでロックは開放されない

データサイズに気を配る
 必要以上に大きなデータ型を使うべきでない
 DATETIMEよりTIMESTAMP
 vacharよりint
 intよりsmallint
 長い文字列はアプリ側で圧縮も検討

範囲検索は注意

ーーーこまかい所のメモが難しいので中略ーーー

 
Insert性能とメモリ量の関係

インサートすると、、、
・リーフがいっぱいだと新しいリーフを作成
・日付のインサートは昇順
・通常はインデックスの並び順に対してレコードはランダムに入る

ランダムIndertはdisk readになる
・インデックス内のエントリを更新するにはそのブロックをメモリバッファ内に収める必要がある

インデックスサイズに注意
・インデックスサイズがメモリに収まればいいけど、そうでない場合は時間がかかる

インメモリインサートでは
・秒間10000r/s
・バッファプール超えた場合
 2000-4000r/s

=> Insertをインメモリで行なうためにインデックスサイズを小さくする

時系列データはレンジパーティション
sharding
 ・5,1のレンジパーティーション

全体のデータのところどころにアクセスするたためには大きなメモリが必要
ブロックを限定してアクセスするような仕組みが必要

covering indexで対処可能
ここが参考になりそう

やっていはいけない事色々

・select * は多用しない(必要な列だけ)
・省スペース化 シリアライズを適当にやったりとか。圧縮できるよね
・TEXT,BLOBを使わない varcharを使うとか

Explainを見る
・UsingIndexでないクエリは使用禁止
・巨大なlimitを注意
・left outer joinを使わない(必要ないデータは返さない)
・ストレージエンジンを混在させない
 ・InnoDBとMyISAMをjoinしたりしない
 ・同一サーバないでは同じストレージエンジン
 ・キューサーバとしてQ4Mを独立させたりはあり
・重複したインデックスを持たない
・ index(c1) index(c1,c2)みたいな
・LOAD DATAは使わない
 ・注意事項色々・・・
 ・バルクインサートとかで対応

と色々書きましたが、書くのが間に合っていない内容が多々あります。すいません