【MySQL】テーブル更新が遅いと思ったら・・【テーブルロック/IO待ち対策】

【MySQL】テーブル更新が遅いと思ったら・・【テーブルロック/IO待ち対策】Web開発者の備忘録MySQLデータベースを用いた、多重更新を行っているシステムがありまして。
それがまた遅いんです。
理由は明確で、該当テーブルがMyISAMだからなのですが。。
そりゃ遅いよね、なんでINNODBにしないの?・・とツッコミが入ることは百も承知ですが、なぜMyISAMだと遅いのか。
それについて語っていきたいと思います。

なぜMyISAMだと遅いのか?

と、書いてしまうととても乱暴なので、どういう場合に遅いのかをきちんと提示しないといけませんね。

「同一テーブルへの更新を、複数人が同時に行っている」

この場合に、涙目になるくらい遅くなります。

理由は、

「MyISAM で出来ているテーブルを更新する時は、テーブルロックが発生するため」

です。

どういう事かというと、誰か一人が updateやinsertをしている間は、みんな待たされてしまいます。

MySQL上で
show processlist;
と入れて、state に「lock」の文字列があれば、そいつが待たされている人です。
lock状態の人が大勢いれば、それは全体の処理遅延となりますので、問題となります。

OS上では、I/O待ちとなります。
% sar コマンドで iowait の数字が高ければまずロックが原因です

I/O待ちの場合、CPU利用率は大抵低いですが、安心してはいけません。
サーバ全体のパフォーマンスに影響しますので(端的に言えば遅くなる)、これを放置すると宜しくありません。

さて、冒頭に出てきました「INNODB」は、テーブルロックではなく行ロックです。
同じ行に対する更新を複数人で行わない限り、待ちが発生することはありません。

という事で、基本はINNODB推奨

MySQL 5.6 リファレンスマニュアル / … / テーブルロックの問題
こちらに詳しく書いてありますが、デフォルトはINNODBとなっております。
※昔は検索ならMyISAMが速い、なんてこともありましたが・・

続きは次回

他にもツッコミ所は残っておりまして。
・なぜINNODBにせずMyISAMにしたのか
・MyISAMからINNODBに何も考えず変更してよいのか?
などありますが、それにつきましては次の機会にでも述べていきたいと思います。