0先日不可解な事象に直面しました、ごく単純な1行のUPDATE文が稀に非常に遅くなる時があったのです。稀に、といいますが検証してみたところ、50回実行して1~2回程度の発生頻度。遅い」などで調べてみたところ、どれにも該当しないように見えました。1万レコード程度といった感じです。うーん、わからん!ということで検証して調査しました。'PRIMARYなID'カラム`id`はPRIMARYです、1カラムで一意に特定できるのでクッソ早いはず。検証では’ランダムな文字列’をphp側で毎回生成し、’PRIMARYなID’は対象を1レコードに絞って、UPDATEを1回するごとにsleepを1秒挟みつつ、50回繰り返すようにしてみました。processlistを見ていました。processlistのプロセス以外にsleepで待ちのプロセスが居ました、おそらくphpが実行中でMySQL側で何も実行されていない時にコネクションだけ残っているものと思います。processlistを実行していたら、変なやつが登場してきました。lock」!こんなん↓Timeのところ、10秒とか経過しているではありませんか!なんや!?貴様!!と、コイツでググってみたところすぐに出てきました。MySQLサーバのプロセスで1つ持っているクエリキャッシュ領域が更新されてロックしているので、それを待っている状態とのこと。クエリキャッシュ領域はDISKよりも高速な記憶領域で、実行されたSQLの結果を記憶しておいて、その後に全く同じSQLが実行されたら、遅いDISKから再度読み込みなおすのではなく、アクセスが速いキャッシュから結果を返しまっせ、というモノ。出てきたことから、どうやら結構コイツに引っかかってしまうことがある模様です。解決方法じゃあ、それは分かったけど、解決策はどないすんねん、というところですが、結論から言うとわたしはまだ解決できておりません・・・ざっくり方法は2つクエリキャッシュを無効にする正直、既に稼働しているシステムで影響が分からないものを無効にする気にはあまりなれなかったのですが、クエリキャッシュを使っていて、むしろ遅延してしまうシステムの場合は無効にするのもアリなようです。遅延してしまうシステム~、というとボヤっとしていますが、参照系よりも更新系が多いシステムなんかが該当するようです。クエリキャッシュが使える状況というのは、1度実行されたSQLと全く同じSQLが実行されるSELECTの結果が全く同じである(1度目のSQL実行からDBが更新されていない)です、まあ当然といえば当然の挙動。更新されるばっかりだと2個目の条件が成立しないので、キャッシュは使われず、SQLは再度実行されることになります。ものは試し!改善されてから影響は考えればいいや~ということで無効にしてみようとしました。変更は以下の構文で行ったのですが、アクセス権限がないってことではじかれてしまいました。query_cache_type=0;うーん、まあ無理ならどうしようもないっすねぇ~、とりあえずレンタルサーバ運営に問い合わせましたが、結果はまだ来ておりません。続報がきたら更新します。SQL_NO_CACHEを使うMySQLのプロセス全体に影響を及ぼさないで、対応する方法もあるようです。`table_name`と思ったんですが、うーむ、どうやらコイツはSELECT文にだけ有効なようで。それもあらためて考えると当たり前で、クエリキャッシュはもともと「1度実行したSQLの結果をキャッシュしておいて、次に全く同じSQLがきたらキャッシュから結果を返す」というモノ、UPDATEの時はキャッシュするとかしないとかではない。UPDATEするということはDBの値が変わるということなので、変更前の値がキャッシュから返されてしまうとマズイ!なので、UPDATEの時は該当のキャッシュがクリアされるような挙動になるはず。なんで、SQL_NO_CACHEで対策する場合には、該当テーブルを参照しているSQLすべてにSQL_NO_CACHEをつけなければいけないことに(たぶん)なるでしょう。́∇`)ノ最終的に・・・クエリキャッシュが無効にできるかはまだ分かりませんが、そもそもの対策として、OLTP系のシステムで頻繁にUPDATEするような処理はなくすという切ない結論になりそうです。今回はセッション系の情報をカラムに持たせていて、pvのたびに更新が発生していたのですが、まあそもそもコイツはいけてなかった。更新頻度は毎回じゃなくてもよかったので、極端にUPDATEされる回数を減らすことにしました。インメモリ系のミドルとかがあれば、そっちで持たせたりとかで対応すべきなんでしょう、わたしが使っているレンタルサーバにはありませんが。コメントをキャンセルメールアドレスが公開されることはありません。FameThemes。