覚えておきたいMySQLのベストプラクティスまとめ…
- May 19th, 2010
- Posted in 開発ツール・技術
- Write comment

「Top 20+ MySQL Best Practices」を読んでへー、と思ったのでメモ的にエントリー。MySQLで高速化なり最適化するためのTipsいろいろです。全部で21個ほど紹介されていますが、個人的にむむ!と思ったものをご紹介。
- クエリーキャッシュを効かせたいときはCURDATE()やNOW()を使わない
CURDATE()は便利ですが、これを使うとクエリーキャッシュが効かないので、場合によってはPHPで一行書いてから次のように使いましょう。
// 悪い例
$r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()");
// 良い例
$today = date("Y-m-d");
$r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'");
selectするときに該当するレコードが一つしかないとわかっているときは「LIMIT 1」を使いましょう。これを使っておけば、全体をスキャンすることがないので速くなりますよ。
ランダムで一つのレコードを取ってくる時によく使う手ですが、RAND()はCPUパワーを使うのであまり使うべきではないとのこと。PHPでごにょごにょしてからやるのが良さそうです。
// 悪い例
$r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1");
// 良い例
$r = mysql_query("SELECT count(*) FROM user");
$d = mysql_fetch_row($r);
$rand = mt_rand(0,$d[0] - 1);
$r = mysql_query("SELECT username FROM user LIMIT $rand, 1");
EXPLAINは知っていましたが、こちらは知りませんでしたよ…。PROCEDURE ANALYSIS()を使えば、格納されているデータを見て、最適な「型」を提案してくれるようです。VARCHARよりENUMが良い、とか教えてくれるっぽいですな。
メンテナンス時などに膨大な数のレコードを削除したりするときは、一気にやるのではなくて、細かく分けた方が良さそうです。そうしないとWebサーバーに負荷をかけてしまうことも。以下のように処理すると良いですね。
while (1) {
mysql_query("DELETE FROM logs WHERE log_date < = '2009-10-01' LIMIT 10000");
if (mysql_affected_rows() == 0) {
// done deleting
break;
}
// 必要ならsleepも。
usleep(50000);
}
他にも原文にはいろいろあるので、覗いてみるといいですね。当たり前の人には当たり前でしょうが、こうしたTipsはコツコツと身につけていきたいものです。
» Top 20+ MySQL Best Practices | TuVinhSoft .,JSC


Limit 1 大事です。
リンク先も拝見しましたが、
ためになる内容でした。
ありがとうございます。