Oracle Databaseの運用時、パフォーマンスが低下してシステムの稼働に影響が出た経験はございませんか?
そのような事態に直面した際は、Oracle Databaseの細かな機能面を把握したうえで、適切な対策を講じなくてはなりません。
今回は、Oracle Databaseの運用時に意識したいポイントを、SQL文やリソース面を中心に解説します。
Oracle Databaseの安定稼働を実現させたい方は、ぜひ参考にしてください。
目次
データベースのパフォーマンス低下が引き起こす問題
IT技術が当然のものとして普及した昨今では、どの企業においても、なんらかのかたちでシステムを利用していることでしょう。
そして、そのシステムに必要不可欠なのが、大量のデータを格納するためのデータベースです。
特にECサイトのような多数の商品を扱うサイトでは、データベースのパフォーマンスがユーザビリティの良し悪しに直結します。
データベースの動作が遅くなると、ユーザーが操作している画面の応答時間も長くなり、結果としてユーザーの直帰率も上がります。
データベースのパフォーマンス低下が、売上機会の損失につながるわけです。
自社サイト・システムを安定稼働させて、ユーザーの満足度を上げるためにも、データベースのパフォーマンス低下はなんとしても避けなくてはなりません。
この記事では、一般的にもポピュラーなデータベースである『Oracle Database』に特化して、パフォーマンス改善のためのポイントを解説していきます。
Oracle Databaseのパフォーマンス低下に備えた事前の対応
パフォーマンスが低下した際にその原因を究明するのも大切ですが、事前に対策を実施しておくことも忘れてはなりません。
Oracle Databaseのパフォーマンス低下を防ぐうえでは、以下で紹介する2つの事項が重要となります。
通常時のシステムの状況を把握しておく
通常時のシステムやデータベースの状況を把握しておけば、パフォーマンス低下時に差分を見ることで、速やかに原因を特定することができます。
また、システムの利用状況や併用するソフトウェアの影響なども加味して、あらかじめボトルネックとなりそうな要素を洗い出しておくのも効果的です。
こうした対応が欠けていると、パフォーマンスチューニングしたとしても、再度同じ問題が発生しかねません。
安定稼働を実現するためにも、データベースの状況はいつでも把握できるようにしておくことが重要です。
OSの統計情報も取得しておく
データベース側だけではなく、OSの統計情報も普段から取得しておきましょう。
なぜなら、パフォーマンス低下の原因が、必ずしもデータベースにあるとは限らないからです。
たとえば、ほかのソフトウェアのせいでメモリーが不足している、そもそもOSのバージョンが古いなどの要因があれば、データベースのパフォーマンスにも影響が表れます。
パフォーマンス低下時に正確に原因を探るためにも、CPUやメモリー、ディスクI/Oなどの統計情報を収集しておくことが大切です。
これらの情報は、UNIX/Linux系の場合はsarやvmstatなどのコマンドから、Windowsの場合はパフォーマンスモニターから確認可能です。
Oracle Databaseのパフォーマンス改善を図る際に意識すべき点
パフォーマンスが低下し、実際に改善作業が必要になった際にも意識したい点がいくつかあります。
問題を切り分ける
始めに問題を切り分けることで、パフォーマンス低下の原因を正確に把握することができます。
先にも述べた通り、OSやハードウェア側のトラブルに起因して、データベースのパフォーマンスが低下する場合もあります。
本当の原因を探るためにも、以下の順番で問題の切り分けを実施していきましょう。
パフォーマンス低下時の問題の切り分けの順番
- ハードウェアトラブルの確認
- OSの情報分析
- データベースの情報分析
ハードウェアの次にOS、データベースの順で問題を切り分けていくのが、このような場合の対応の定石です。
原因次第では、CPUやメモリーなどのリソースを増やすだけで、パフォーマンスの問題を解決できるかもしれません。
待機イベントを確認する
待機イベントから処理待ちとなっているプロセスを確認するのも、原因を特定するうえでは非常に効果的な手段です。
特定のプロセスにCPUが割り当てられず処理待ちとなると、待機時間とともに待機イベントに記録されます。
そこで、大量の待機中プロセス、または長時間待機しているプロセスが確認できる場合は、CPUのリソースに関してなんらかの問題が発生しているとみなせます。
その際は、大量のCPUを消費しているセッションがないか調査して、該当するものがあれば利用状況を見直し、必要に応じて切断してください。
また、実行しようとしたSQL文が最適化されていない可能性もあるので、セッションに問題がなければ実行計画を見直しましょう。
なお、こうした待機イベントは、Oracle Databaseでは動的パフォーマンスビューやStatspackなどの機能を利用して確認することが可能です。
原因を特定してから1つずつチューニングを行う
チューニング作業は、必ずボトルネックを特定してから実施しましょう。
原因が明らかになっていない状態でチューニングすると、別の問題が新たに発生するおそれがあるためです。
同様の理由から、複数の変更を同時に反映するのもおすすめできません。
ボトルネックの特定を急ぎたいのであれば、Oracle Databaseが備える機能を最大限活用することが重要です。
先に紹介した動的パフォーマンスビューでは、待機イベントのほかにも、さまざまなデータベースアクティビティの最新状態をチェックできます。
最新状態ではなく、累計のデータや平均値が見たい場合にはStatspackを活用するのがおすすめです。
両者は確認できる範囲が異なるので、併用して情報収集を行うのが効果的です。
Oracle Databaseのパフォーマンスを改善するポイント
パフォーマンス低下の原因がSQLや実行計画など、データベース側にある場合は、適宜チューニングなどを行い対処しなくてはなりません。
ここからは、原因となる可能性が高いポイントをいくつかピックアップして、それぞれの場合の対策を解説していきます。
SQL
データベース側の改善点としてまず考えられるのは、実行するSQL文です。
最適化されていないSQL文が多く存在すると、想定以上にメモリーやディスクI/Oが消費され、パフォーマンスの低下を招きます。
パフォーマンスに影響を及ぼすSQL文としてよくある例と、それに対する改善ポイントは以下の通りです。
ワイルドカードを使用している
「SELECT *」のようなワイルドカード(*)を使用するSQL文は、基本的には避けるべきでしょう。
必要のない列まで指定するとオーバーヘッドが発生し、データベースのパフォーマンスに影響を与えてしまいます。
SELECT文に限らず、SQL文は必要な列のみを指定するのがもっとも効率的です。
また、対象の列を明記しておけばソースの可読性も向上するので、仕様変更の際にも少ない負担で対応できます。
WHERE句で演算式や関数を用いている
WHERE句で演算式や関数を用いると、インデックスが利用されず意図した通りにSQL文が実行されない場合があります。
たとえば以下のSQL文では、WHERE句にcol2が指定されていても反映されず、全列に対して計算が実行されます。
SELECT col1 FROM sample WHERE col2 * 2 > 10000;
インデックスを機能させるためには、以下のように記述しなくてはなりません。
SELECT col1 FROM sample WHERE col2 > 10000 / 2;
ほかにも、条件に否定形を使う、NULLを指定しているなどでも想定外の結果となってしまうので、WHERE句の使い方には注意しましょう。
実行計画
Oracle Databaseでは、実行計画に沿った手順でSQL文が実行されます。
そのため、SQL文そのものが最適化されていても、実行計画に問題があるとパフォーマンスに影響してしまうのです。
ほとんどの場合、実行計画はコードオプティマイザによって最適化されたものが選択・実施されます。
しかしなんらかの要因で、意図していたもの以外の実行計画が選択されてしまうケースも少なからず存在します。
この影響で、毎日パッチで動いている実行計画が勝手に変更されるようなことがあっては、システムの安定稼働は目指せません。
実行計画を固定化する方法としては、ヒント句の利用が挙げられます。
ヒント句を使えば、インデックスや結合の順番を明示的に指定できるので、意図していない実行計画が実施されるのを防げます。
ヒント句については公式のリファレンスに詳細が記載されているので、利用する際はぜひそちらをご覧ください。
参照元:Oracle® Database SQL言語リファレンス 23ai
システムグローバル領域
システムグローバル領域(SGA)とは、Oracle Databaseの全プロセスに共通のメモリー領域のことです。
パフォーマンスを向上させるうえでは、このSGAを効率よく各プロセスに割り当てる必要があります。
SGAの効率的な利用を目指すためには、まず、解析済みSQL文の共有率を高めることが大切です。
一度実行されたSQL文は、SGA内の共有プールにキャッシュされ、以降同じSQL文はそこから再利用されるようになります。
しかし、大文字・小文字が違ったり、インデントの入れ方が異なったりすると、実行結果が同じでも同一のSQL文とみなされません。
そうなると共有プールから再利用されず、結果としてCPUなどのリソースを圧迫し、パフォーマンスの低下を招いてしまうのです。
この問題はSQL文の表記揺れをなくせば解消されるので、社内やチーム内でのコーディングルールやフォーマットを必ず統一しましょう。
また共有プールのほかにも、REDOログ・バッファの設定の見直しや、バッファ・キャッシュのサイズの変更でもSGAの利用状況を改善できます。
プログラムグローバル領域
Oracle Databaseには、プロセスごとに割り当てられるプログラムグローバル領域(PGA)も存在します。
パフォーマンス低下が、メモリー使用率の急激な上昇によって引き起こされている場合は、このPGAに原因があると考えられます。
この場合は、動的パフォーマンスビューから大量のメモリーを使用しているプロセスを特定し、対処しましょう。
なお、自動PGAメモリー管理機能を有効にしている場合は、PGAで使用されるメモリーのサイズが自動で設定されます。
この際、PGA_AGGREGATE_TARGETというパラメータで、目安となるサイズを指定することが可能です。
ただし、その値以上のメモリーが割り当てられるケースも少なくないため、自動管理が有効でもリソースの監視は必ず継続してください。
データファイル
データファイルに対するI/Oの改善も、パフォーマンス向上のためには欠かせません。
特定のデータファイルにのみI/Oが集中すると高負荷がかかり、データベース全体のパフォーマンスにも影響を与えます。
この問題は、アクセスが集中しているファイルを複数のディスクに分散配置し、負荷も分散させることで対処可能です。
また先にも述べたように、全表ではなく必要な列だけを指定してSQL文を実行することも、不要なI/Oの抑制につながります。
もし、I/Oが集中しているファイルが分からないのであれば、Statspackの利用をおすすめします。
File IO Statsから、I/Oが頻繁に発生しているファイルを瞬時に特定可能です。
REDOログ・ファイル
REDOログ・ファイルへの書き込みで待ちが発生すると、その間データベースにも待機時間が発生してしまいます。
データファイル同様、REDOログ・ファイルも分散配置すれば、このような待機時間の発生を未然に防ぐことが可能です。
くわえて、分散させることで障害発生時の影響も軽減できます。
また、REDOログ・ファイルのサイズが大きいほど、パフォーマンスも向上することが知られています。
分散配置でもパフォーマンスに改善がみられない場合は、サイズを調整してみるのも一つの手です。
Oracle Database のパフォーマンスはSQL文の最適化や実行計画の固定などにより改善できる
今回は、Oracle Databaseのパフォーマンスを改善する方法を、SQLを中心にさまざまな観点から解説しました。
Oracle Databaseのパフォーマンスが低下した際は、SQL文の内容や実行計画の見直しを実施しましょう。
特にSQL文は、関数の使い方や表記の違いといった些細なポイントでも、結果としてパフォーマンスに大きな影響を与える可能性があります。
また、ハードウェアやOS側の問題でパフォーマンスが低下する場合もあるので、SQLのチューニングを実施する前に、問題の切り分けを行うことも非常に大切です。
もし上記のような対応が難しい場合は、ぜひコーソルにお任せください。
Oracle Databaseに精通したプロフェッショナルが、安定稼働のために徹底的にサポートさせていただきます。