MySQLのチューニングは、多くのデータベース開発の場で必須の知識です。が、単にmy.cnf等で設定するパラメータのチューニングだけを考えていても、必ずしも良い結果を生むとは限りません。よりパフォーマンスの高い状態でMySQLを動作させるには、稼動させるサーバの状態や、メモリ管理そのものを知っていなければならないでしょう。
ご存知の通り、MySQLは登場当初から高速な動作で高い評価を得ています。もしMySQLのパフォーマンスが悪いと感じられるのであれば、一番最初から既に間違っていると考えて構いません。CPU/メモリ/ストレージなどサーバー能力の見積り・テーブルの設計・ストレージエンジンの選定・テーブルの設計・クエリの投げ方など、これらを決めて導入・設計した企業のミス=MySQLをうまく動かせない・と申し上げてもいいんじゃないかと思います。
それでは、MySQLのパフォーマンス向上の為に、もう少し突っ込んだチューニングのヒントは何か?を、表題にある「仮想メモリ」と絡めながら考えてみましょう。Linuxに限らず、現在主流のCPUに対応するOSは、プロセスを「仮想メモリ空間」にアドレッシングして実行しています。もし、PCに1Gのメモリしか搭載していなくても、一つのプロセスは4Gバイトのメモリ空間を独自に持っています(※32bitの場合。また、ユーザーエリアとしては4G全部使えるわけではない)。基本的に、このプロセスが持っているメモリ空間(の一部)を、実メモリに再配置して実行しているのが、現在のOSです。
間違えて思い込んでしまう一つの例として、「ハードディスクのスワップ領域にプログラムやデータを退避させ、必要になったらメモリに読み込む」ことを、仮想メモリ管理だと思ってしまうことがあります。ですが、これは仮想メモリ管理のうちの、一つの技術です。スワップが発生するのは、「稼動しているプロセス(群)のプログラムやデータが実メモリに配置されつくしてしまい、やむなくハードディスクを利用している」状態であると考えた方が、正しい理解になります。確かに、昔のOSでは常にそのように動作するものがありました(※実メモリ上にプロセスのメモリを全て配置しようとするメモリ管理のやり方)。しかし、現在の仮想メモリ管理では、メモリ活用の効率化が進み、メモリ連続性の確保など、もっと進化した方法が取り入れられています。
ですから、仮想メモリ管理を知らずにMySQLでチューニングを考えてしまうと、「あまりバッファを割り当てすぎると、すぐにページアウトしてしまってパフォーマンスが逆に落ちてしまうのではないか?」などの心配が出てきます。が、仮想メモリ管理がどのように行われているかがわかれば、バランスを考えたチューニングが可能になります。サーバの選定やパフォーマンスを最大に出すことについては、データベースの利用目的・想定されるアクセス量・MySQLを使用した上での経験則など、個人の所有するノウハウに関わってきます(ので、ここにあまり詳しく書くことは出来ません)。
先に仮想メモリの話をしましたが、実メモリ(一時記憶)にマッピングされて、実メモリだけで実行されている状態が、もっともプロセスの動作パフォーマンスがいいことは当然です。そこで、「サーバの実メモリと動作するプロセス全てを考慮して、MySQLが最も効率よく動作するメモリ配分」をロジカルに探すことが大切になります。「ハードディスクを早いものに交換しよう・RAIDを導入しよう」「CPUを高速なものにしてみよう」「メモリを増やしてみよう」などのハードウェアによるパフォーマンス向上アプローチは、確かに効果をもたらしますが、それらは、はっきりと“ハードウェアが足を引っ張っている”ことが明らかなときに実施されるべきであり、まずはMySQLが稼動しているサーバの動作状況を見直すことが、先手だと思います。
では、サーバの何を見ればいいのか?ヒントとしては、プロセスがどのようにメモリを使用しているかを調べることです。もし、MySQLのパフォーマンスが低く、尚且つMySQLが十分なメモリを使用していないのであれば、my.cnfでバッファを増やせば、パフォーマンスの底上げが出来る可能性があります。同様に、パフォーマンスが悪いにもかかわらず、MySQLに対してメモリが十分にマッピングされているのであれば、MySQLに指示しているバッファの割り当てのやり方に問題があると考えることが出来ます(※無駄なバッファに多くメモリを割り当ててあり、肝心なところにメモリが使われていない等)。
もし本当にパフォーマンスを上げようと考えるのであれば、“MySQL 高速化 チューニング”などでググったパラメータを、そのまま書き込んでも意味がありません。MySQL:サーバパラメータのチューニングのマニュアルに書かれている値や、「このパラメータには、だいたいnMバイトくらい割り当てればいいでしょう」などという情報には、自分で使う環境に関しては全く根拠がないことを、理解しなければなりません。my.cnfに設定するパラメータや値については、MySQLのshow status;コマンドで当たりを付けることが出来ますので、そこで調整を取る必要があるでしょう。
ということで、具体的に高速化をするには、それぞれの使われ方でそれぞれ最適な値がある・というまとめになってしまい、本当にMySQLの動作状態を見るなら、当方が実際に見てみるしか正解は出せないのですが、ちょっとだけ有効なヒントを出してみます。仮想メモリ管理と併せてサーバパラメータのチューニングを考えるなら、設定する値に、実メモリを意識しすぎてケチ臭い値を与えるくらいなら、ガバッと大きめの値を設定する方がまだマシなのです。もちろん、大きすぎる値はそれこそメモリのスワップアウトを起こしてパフォーマンス低下になりますが…。
MySQLのチューニングは奥が深いので、クエリキャッシュやキーバッファ・ソートバッファなどに設定する値だけを気にするのではなくて、サーバのメモリ環境全体を見通してチューニングを行う必要があります。サーバが効率的に動いている状態を見るのは、気持ちのいいものです。IT業界の悲惨な労働環境が伝聞されますが、単なるつまらない仕事にしないために、こういった点も面白がって勉強する人は貴重な存在です。そういう人を、IT業のトップはすり減らしてはいけませんね。