システム負荷がパフォーマンスに与える影響


チューニングしたクエリがインデックスを使うようになると、 複合インデックスを定義することを考えなくなってしまうことがあります。 しかし、オプティマイザがそのインデックスを使うのは、クエリに対する 「適切な」インデックスだからというより、フルテーブルスキャンよりも 効率がいいからという方が正しいと言えます。つまりそれは、最適化 されたインデックスだとは言い難いでしょう。

前の例では、実行計画において間違った列の順番を認識する難しさを 表しました。多くの場合、述語情報はうまく隠されてしまっており、 インデックスの使用法が最適化されているかどうかを確認するのに、 述語情報を調べなくてはなりません。

例として、SQL Server Management Studioでは 図にあるように、 インデックスの処理単位にマウスカーソルを載せた(hoverした)時にだけ、 ツールチップとして述語情報が表示されます。この実行計画では、 SCALE_SLOWインデックスが使われており、ID2に 対する条件がフィルタ述語であると表示されています (「Seek Predicades」ではなく「Predicate」の方)。

図3.3 述語情報のツールチップ


MySQLPostgreSQLの実行計画から述語情報を 取り出すのは、さらに厄介です。付録Aでさらに詳しく説明しています。

実行計画の中で述語情報がどんなに小さく表示されていたとしても、 それがパフォーマンスに大きな影響を与えるのは間違いありません。 システムが成長していく時はなおさらです。成長していくのはデータ量だけでは なく、アクセス量も増えていくことをもう一度考えてみましょう。アクセス量は、 スケーラビリティの関数のもう1つのパラメータであると言えます。

このウェブサイトにぴったりのカップは僕たちのショップにあります。
#見た目もいい感じだし、ここでの僕の仕事を支えてくれています

図 3.4では、 データ量を一定とした場合の、アクセス量に応じた応答時間を 表しています。前の例と同じクエリで、常に最もデータ量の大きい セクションを指定した場合の実行時間です。つまり、 図 3.2の最後の 点と同じです。

図3.4 システム負荷に対するスケーラビリティ


点線は、SCALE_SLOWインデックスを使った時の 応答時間です。同時に25クエリが動いている時は、32秒までグラフが 伸びています。全く負荷がない、つまり開発環境と同じような状態と比べて、 30倍の時間がかかっていることになります。開発環境に本番環境の完全な コピーデータがあるとしても、バックグラウンドの負荷は、本番環境における クエリの実行速度を遅くする原因になり得るのです。

実線は、フィルタ述語を一切持たないSCALE_FAST インデックスを使った時の応答時間を表しています。こちらは、 25クエリが同時に動いている時でも、応答時間は2秒以下を保っています。

注記

注意深い実行計画の調査結果は、 うわべだけのベンチマークよりも信用のおけるものです。

完全な負荷テストは意味のあることですが、そのための手間は かかります。

問題になる可能性のある応答時間は、開発中は軽視されている ことがよくあります。これは、我々が「本番のより強力なハードウェア」が あるのだからもっと良いパフォーマンスが出るはずと思い込んでしまうことに 原因があります。どちらかと言えば、本番環境の方がより複雑な構成になるため、 開発環境では起こり得なかったレイテンシの蓄積によって、逆の結果になることも 多いようです。本番環境と同等のインフラでテストした時でも、バックグラウンドの 負荷が応答時間の違いの原因になってしまうこともあります。次の節では、 「より強力なハードウェア」により高速なレスポンスを期待するのが間違いである という話を取り上げます。

Photo of Markus Winand
Markus Winand氏は、開発者がSQLパフォーマンスを改善するお手伝いをしています。 彼は、SQL Performance Explainedの 著者でもあり、出張トレーニングhttp://winand.at/での リモート講義も 行っています。