③ チューニングプランの計画
④ チューニング実施
さて、お待たせしました。ここまできてようやくチューニング実施となります。
チューニングの手段は、治療のための薬剤や手術の種類が多様であるのと同じように、多様な方法が用意されています。しかし、人間の体が人種や年齢を問わずほぼ同じ構造をしているのに対し、DBMSにはそれぞれ特徴とクセがあるため、使用できるチューニングプランもかなり実装依存となります[5]。そのため本稿では、チューニングプラン計画のための大方針である、リソースの使い方という一般的な観点から、チューニングについてまとめてみたいと思います。
チューニングをリソースという観点から分類すると、正反対の方法が2種類存在します。つまり、リソースをより多く使わせるチューニングと、リソース消費を抑えるチューニングです。
リソースをより多く使わせるチューニング
リソースを多く使わせることがチューニングにつながるケースとは、たとえば、前節で解説したコネクションのプール数が少ないことにより流量が絞られている場合です。こういうときは、プールの数を増やしてもっと同時に多くのコネクションがリソースを使えるようにしてやる必要があります。ちょうど閉めていた水門のバルブを開くイメージです。もちろん、開き過ぎて逆にリソースを枯渇させたら本末転倒ですので、効果を注意深くモニタする必要があります。
リソース消費を増やすことがチューニングとなるもう一つのケースは、処理の並列化が可能な場合です。DBで言えば、パラレルクエリの機能がこれに相当します。特にCPUのリソースに余裕がある場合は、マルチコアプロセッサを効率良く使える技術です。
厳密に見ると、このタイプのチューニングを本当にチューニングと呼んでよいかどうかは若干の疑問が残ります。というのも、確かにリソース消費を増やすことで処理時間は短くなりますが、その分リソース消費が増えるわけで、「処理時間×消費リソース」という全体の面積は変わらないからです(図5)。無論、リソースを効率的に使用するというのは(特に他ユーザへの影響を気にしなくてよいバッチ系のシステムでは)、一概に悪いことではないのですが、これが一種のトレードオフであることは事実です。そのため、このタイプのチューニング後にはリソース枯渇を招いたり、他ユーザが実行する処理の性能に影響を与えるリスクが高まるというコストを負うことになります。
リソース消費を抑えるチューニング
他方、リソースを使わせない方向でのチューニングもあります。むしろ、一般的に筆者たちがチューニングと聞いて連想する技術の多くはこちらに属します。DB関連の技術としては、インデックス、パーティション、ヒントによる実行計画の変更があります。こうしたチューニングが有効なケースは、先ほどとは逆にOSリソースにボトルネックが見られる場合です。そして、DBにおいて最もボトルネックになる可能性が高いリソースはディスクです。CPUやネットワークがボトルネックになるのは相対的にはレアケースです。
事実、インデックスもパーティションも、ディスクへのアクセス量を減らすための技術です。ヒントで実行計画を変える際も、基本的にはいかにディスクからの読み出し量を減らすか、という観点で行います。このタイプのチューニングは、いわば処理時間(x軸)もリソース消費量(y軸)も小さくすることを目的にしています。理由は、このタイプのチューニングのほうが、トレードオフで失うものが少ないからです[6]。
どちらのタイプのチューニングが有効かは、検査・診断の結果、ボトルネックがどこに存在しているか、およびシステムの特性(バッチかオンラインか)によります。
効果測定
チューニングを実施したら、その成果が現れるか、もう一度測定を行う必要があります。時には期待通りの結果が得られなかったり、悪くするとさらに病状を悪化させてしまっていることもあるので、効果測定は絶対に必要です。
基本的に、図1の①②のときに行ったのと同じ環境でもう一度処理を実行し、性能測定を行えばよいのですが、1 点だけ注意が必要なことは、一度の効果測定で測るチューニングは1つだけに制限することです。これは、複数の変数を一度に変えてしまうと、ある治療単独の効果がわからないからです。時間がないときは、一度に複数のチューニングを施したいという誘惑に駆られることもあるかもしれません。ただ、断言してもよいですが、そうすると結局あとでもう一度測定しなおしになって二度手間になります。「急がば回れ」の格言が教えるとおり、治療は一歩一歩着実にやりましょう。
データベースの鉄則
効果測定のとき、変える変数は1つだけ
まとめ
本稿では、パフォーマンスチューニングの具体的な実施手順を解説してきました。パフォーマンスチューニングという仕事の大きな特徴は、システム全体を見なければいけないことです。遅延が発生する個所がいつもDBなのであれば(たしかにDBはボトルネックになりやすいのですが)、DBだけ見ていればよいでしょうが、システムがそうこちらに都合の良い原因で遅くなっているわけではありません。それは、医者が患者に向かって「私が治せる病気にだけかかるようにしてください」とお願いできないのと同じです。
このように、「システムを全体として見る」というところも、パフォーマンスチューニングが医者の仕事に似ている点の一つです。医者もまた、たとえ担ぎこまれた患者の病気が自分の不得手な分野の場合でも、やはり責任持って診察に当たらねばなりません。まあ、そうは言っても、医者が自分の専門を持っているように、エンジニアにもやはり得手不得手があります。筆者としても、切り分けの結果アプリケーションやクライアントサイドの問題だとわかれば、あとは専門医に任せてしまうことも多いです[7]。
それでは、本稿の重要ポイントをまとめましょう。
- パフォーマンスチューニングは医者の治療に似ている
- チューニングの前に診察と検査がある。というより仕事のほとんどはそれが占める
- 処理が遅い原因を突き詰めると、「OSリソースの消費」と「流量制限」の2つ
- OSリソースが原因の場合、パフォーマンスは「最も弱い環」に引きずられる
演習問題はこちらです。
演習問題
あなたの使うDBMSでSQLの滞留時間を調べる手段について調べなさい。
解答解説は、いつものとおり筆者のWebサイトおよび技術評論社のWebサイトで公開します。
連載の終わりに
さて、「DBアタマアカデミー」は今回で終了となります。1年間(昨年の「SQLアタマアカデミー」から継続して読んでいただいていれば2年間)お付き合いいただきありがとうございました。次号からは、今までとはちょっと趣を変えて、より現場に即した内容をお届けしようと考えています。こちらも、どうぞお楽しみに。
参考資料
- Microsoft TechNet ライブラリ「ファースト ステップ ガイド - パフォーマンスの監視」
- WindowsでOSリソースを取得する機能「パフォーマンスモニタ」の解説です。
- 小田圭二「門外不出のOracle現場ワザ」「第5章 DBアクセスの空白地帯 コネクションプーリングを極める」
- DBMSはOracle限定ですが、コネクションプール一般について参考になります。コネクションプールが枯渇した場合の動作はこのテキストの分類に倣(なら)いました。