カテゴリー別アーカイブ: LAMP[Linux, Apache, MySQL, PHP]

mysql チューニング – 上物 explain mysqldumpslow

インフラ的なチューニング項目もあるけど、今回は上物のチューニング。

上物のチューニングといえば、「Wordpressでページ送りが表示されない」の記事で出てきたEXPLAIN文。
こいつは、SQL文の前にEXPLAINとつけて実行すると、そのSQL文が実行されるときの実行計画が表示される。

また、チューニングするには情報収集が大事で、クエリのログを取得するのが第一歩。
長時間を要するログを取得するのに、MySQLアップデート - epel/remiリポジトリでやったスロークエリログを取得するほかに、

my.cnf

log = /var/log/mysql-query.log

の様に記述することで、クエリ等のログを取得できるが、スロークエリの方が解析しやすいと思う。
で、取得したスローログは、mysqldumpslowコマンドで処理できる。

mysqldumpslow -s t all-sql.log >sorted.txt

の様に実行することで、総消費時間(実行時間x実行回数)順でソートしたSQL文一覧が出力されるので、これの上からチューニングを施していく。

SQLのチューニングと言えばインデックスを張ることで、ユニークなキー、クエリの要素を出来るだけ多く含んだキーを設定することで速度的に大きな恩恵が得られる事が多い。
そして、インデックスがどのように働くかというのを知る方法が、冒頭に述べたEXPLAIN文である。
sorted.txt

Count: 11108  Time=0.04s (451s)  Lock=0.00s (0s)  Rows=0.0 (425), est_bk[est]@localhost
SELECT price FROM est WHERE r_id = ‘S’ AND s_id =N LIMIT N

の様に出てきた場合、平均実行時間0.04秒のクエリが11108回実行されていると言うことになる。このSQL文を

EXPLAIN SELECT price FROM est WHERE r_id = ‘S’ AND s_id =0 LIMIT 10

等の様に実行する(S/Nは文字列・数値の代替文字なので、適宜数値などを設定する)

実行結果は

id select_type table type possible_keys
1 SIMPLE est ALL NULL
key key_len ref rows Extra
NULL NULL NULL 5935 Using where

のように出力される。
この場合、SIMPLE(UNION等を含まない)セレクトがestテーブルに実行されて、有効キーはなく5935行をALL(全域スキャン)を行う計画になっている。 全域スキャンはコストが高いので、インデックスを設定することで高速化できそう。
確認のため、インデックスを張る前に、EXPLAINを外して普通に実行すると、クエリの実行時間 0.0580 秒であった。

ALTER TABLE est ADD INDEX INDEX_R_S_PRICE ( r_id , s_id )

のようにしてインデックスを張って、再度、EXPLAIN文を実行すると

id select_type table type possible_keys
1 SIMPLE est ref INDEX_R_S_PRICE
key key_len ref rows Extra
INDEX_R_S_PRICE 44 const,const 1 Using where

のように、INDEX_R_S_PRICEが有効化された。
この状態で、再度、EXPLAINを外した文を実行すると、クエリの実行時間 0.0009 秒となった。
これで、インデックスを張る前よりも1.55%まで処理時間を短縮できた事になる。

同様の手法で、ログを上から片付けていけばDB動作の高速化が望める(但し、インデックスを張りすぎると、INSERT等の更新系処理で、インデックスを構築する負荷が増加するのに注意が必要)

(350)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], MySQL | コメントをどうぞ

基本コマンド3

jobs

バックグラウンドジョブを表示する。
バックグラウンドジョブは

コマンド &

の様に、最後に&を付けて実行することで、コマンドが完了する前に操作がコマンドラインに戻ってきて、実行されたコマンドはバックグラウンドジョブになる。 圧縮処理とか、時間がかかりそうなコマンドをバックグラウンド実行して、コマンドライン操作を続けたりする。

コマンドの実行中にctrl+zを入力すると、そのコマンドがバックグラウンドの待機状態になって、コマンドラインに戻る。

バックグラウンドジョブは

fg ジョブ番号
bg ジョブ番号
stop ジョブ番号

の3種類のコマンドで操作できて、fgならフォアグランド実行(通常の実行状態)に戻し、bgならバックグラウンド実行、stopなら待機状態にする。

ジョブは

kill %ジョブ番号

で停止することができる。

killコマンドは、送るシグナルの種類を指定できる(kill -SIGHUP, kill -SIGALRM等) 、サーバプログラム等では、このシグナルにより、リロードしたりする。

ジョブではなく、プロセスを表示するには

ps

コマンドを利用する。 よく使われるオプションはax(a:全ユーザ、x:端末制御外)で、httpd等のプロセスが表示されるので、基本コマンドの組み合わせで ps ax|grep httpd|wc等とすると、現在動作中のhttpdの数を知ることができる。

プロセスはジョブと同様、killコマンドで操作できる(kill プロセス番号)

(416)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

基本コマンド2

grep
grep 検索語 検索ファイル
検索ファイル中の検索語を含む行を表示する。

grep hoge.com /var/log/httpd/*
cat /var/log/access*|grep hoge.com
のように、他から流し込むこともできる。

df
ディスクの空き状況を表示する。

free
メモリの空き状況を表示する。

wc
行数を知る。
grep error error_log|wc
みたいに繋ぐと、該当語がある行数を簡単に調べたり出来る

(85)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

vim – 設定&編集

Linuxの定番エディタvimの設定

vimrc

set fileencodings=utf-8
set encoding=utf-8
set termencoding=utf-8

UTF-8環境の設定。 termencodingはbashrcとあわせる(デフォルトのbashはeuc-jpになっている)

set autoindent
set tabstop=4

オートインデントの有効化と、ハードタブの文字数。 編集中に一時的に無効化する場合

set number

行数を表示する。

set showmatch

検索でヒットした部分をハイライトする。

vimの基本操作

:w

保存

:q

終了
合わせ技で:wq(保存終了)とか。
編集内容を破棄して終了するなら!をつけて、:q!にする。

gg
GG

ファイルエンドトップ/エンドへ

/検索語

検索。 検索後はnで次のヒットへ、Nで前のヒットへ

%s/検索語/置換/オプション

置換。 オプションはgでファイル全体、cで確認表示(確認+ファイル全体ならgc) 正規表現を使って高度な置換が出来る。

u

元に戻す。 戻しすぎたら、ctrl+r

yy
dd
p
P

1行コピー、1行削除、次の行に貼り付け、前の行に貼り付け。
ddで削除すると、削除内容が自動でバッファに入るので、yy>dd>pの動作をするとコピーしておいた内容が消えるので順序に注意。
複数行ならy行数 enter, d行数 enterとか。

(196)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

PHP 関数がどこから呼ばれたか調べたり & PHP定数

 PHPで共有ファンクションを使っているけど、それがどこから呼ばれているか知らなきゃならないことがある。
 こういうときに利用できる関数がdebug_backtrace()というファンクション。
 PHPでFatalエラーが出たときとかに呼び出し関係を表示したり出来るのはこの仕組みが働いている。
var_dump(debug_backtrace());
とか埋め込んでおくと、その関数が呼ばれたときに、呼び出し関係と各要素のダンプがみられる。

あまりスマートではないけど、ある関数で、特定のコードから呼び出されたら処理を変更したいって言うことがあるが
$backtrace = debug_backtrace();
if($backtrace[2][‘args’][0][‘logic_file’]==’parts/stockman.php’)
の様にして、バックトレースの要素を使って分岐すると言うことも出来る。

PHPの便利な定数。
PHPには便利な変数($_SERVER等)があってよく使われているけど、定数もいくらかそろっていて、これがデバッグ向けの物がほとんどなので、debugネタのついでにメモ。
__LINE__ 行番号。 「__LINE__.’で問題が発生しました’」みたいに例外を投げてみたり。
__FILE__ ファイルのフルパスとファイル名。 変数からも取得できるけどこっちの方が書きやすい。
__DIR__ ファイルの存在するディレクトリ。 dirname(__FILE__)と同義。
__FUNCTION__ 現在の関数名。
__CLASS__ 現在のクラス名。 継承した時に、継承元で定義してある__CLASS__を使ったメソッドを、継承先で呼び出しても継承元のクラス名が戻ってくる点に注意(継承先でも同じメソッドを定義して__CLASS__を呼んでやれば、継承先のクラス名がとれる) これに対して、get_class($this)を呼ぶと、継承先で呼び出せば継承先のクラス名が戻ってくる(まぁ、インスタンスの名前だから当たり前だが)
__METHOD__ 現在の(クラス)メソッド名。
__NAMESPACE__ 現在の名前空間。 名前空間が実装されたのが最近なんで使ったことがない。

(3214)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], PHP | コメントをどうぞ

ディスプレイの違い

 開発って言うかデザイン?
 Webサイトを作る時って、デザイナーが作るわけだけど、彼らの使うディスプレイって、色の良く出るVAやIPSの良質なディスプレイな事が多いし、ビデオカードもQuadroとかFireProとかが載ってたりする。
 他方、ライトユーザはオンボードビデオに安いTNディスプレイを使っていたりして、発色がめちゃくちゃなことがある。
 作業場のPCで淡いカラーリングを施したページを家電量販店の安いPCで表示したら真っ白って事があったり。
 昔は、デザイナーの作業の最終地点が印刷物で、AdobeカラーマッチングしたCMYKで作って、色分解して印刷所に出せば、印刷機とマッチングできているから綺麗に出てきていたわけだけど、今の最終地点はWebが多く、ここのクライアント環境は色々な物があるので、ある程度色をきつめに作っておかないとダメだったり、色がおかしく(良くある青白いもの意外に、赤傾向や緑傾向な環境もあったり)なったりすることもあるのだが、まぁ、この辺は作る側じゃどうしようもないんで、せいぜい、淡い色をちょっと濃い目にして、発色の弱い環境でも消えないようにするくらいしかないな(デザイナーがいくらマッチングしても、結局、クライアントがマッチングできていないのだから)

(83)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

MySQLと文字コードと

まじめも:collationでUTF8日本語を使う場合、候補にutf8_general_ciとutf8_unicode_ciのどちらを選ぶか迷う事がある

これについては、
MySQL5.5ユニコードキャラクタセットの説明
の中程に

For any Unicode character set, operations performed using the xxx_general_ci collation are faster than those for the xxx_unicode_ci collation.

A difference between the collations is that this is true for utf8_general_ci:
ß = s
Whereas this is true for utf8_unicode_ci, which supports the German DIN-1 ordering (also known as dictionary order):
ß = ss

generalはunicodeに比べて高速だと書かれている。
挙動の違いとして、上記エスツェット(ドイツ語拡張文字)の違いが挙げられているが、現在の書法ではss(unicodeの挙動)が正しい。
しかし、日本語の扱いの違いが上げられていないが、実際に評価すると以下の様な挙動を示す。

test_table
id name
1 ユニコード
2 ゆにこーど
SELECT * FROM test_table WHERE name LIKE ‘%ゆにこーど%’;
collation設定 id name
unicode 1 ユニコード
2 ゆにこーど
general 2 ゆにこーど

utf8_unicode_ciにすると、なんとカタカナとひらがな表記が同じであると判定されてしまうのだ。
これだと、実運用上問題が生じることが多いだろうから、一般的には、utf8_unicode_ciではなくutf8_general_ciを使う様にした方がいい。

(306)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], MySQL | コメントをどうぞ