DBMSからデータを抽出・更新するとき、SQLを入力し、データベースで実行します。このとき、データベースでどのようにSQLが実行されるか、ご存じでしょうか。
同じ結果を出力するSQLも、SQLの内容が異なればデータベース内での実行のされ方が異なります。SQLがデータベースでどのように実行されるか、その具体的な内容を示したものが「実行計画」です。効率のよいSQLを作成するには、実行計画を理解することが重要です。
本記事ではOracle Database(以下、Oracle)を例に、実行計画とはなにか、実行計画の見方からチューニング方法まで、詳しく解説していきます。
実行計画とは
実行計画とは、OracleがSQLを実行するために使用される手順の組合せです。Oracleでは、実行計画は内部コンポーネントのCBO(コストベースオプティマイザ)が作成します。
以下は、実行計画の一例です。
CBOは、データ量や統計情報(オプティマイザ統計)などの情報をもとに、最適な実行計画を作成します。しかし、同じSQLであればいつも同じ実行計画が作成されるとは限りません。たとえば、データ量が大きく変更されたときや、統計情報が古いままだと適切な実行計画が作成されず、パフォーマンスが低下する場合もあります。
実行計画のコストとは
実行計画に出力されているコスト(Cost)とは、CBOがSQLを実行する際に使用するリソースを表したものです。リソースは、CPU使用量やメモリ使用量、Disk I/Oなどから算出されます。たとえば、多くのデータをディスクから読み込む場合では、コストは高くなります。
CBOは、統計情報や初期化パラメータをもとにコストを見積もり、SQLを実行するうえで最もコストが低いアクセスパスを選択します。ここでも、統計情報が古く、正確な統計情報が収集されていなければ、最適なアクセスパスが選択されません。
Oracleでは、夜間に統計情報が取得されるようにデフォルトで処理が組み込まれており、統計情報がとられていないことによるパフォーマンス劣化を防ぐ仕組みが備わっています。
実行計画の確認方法
実行したSQLに対して、CBOが作成した実行計画を確認するには、いくつか方法があります。ここでは、その中でもEXPLAIN PLANによる確認方法をご紹介します。
EXPLAIN PLAN文を実行すると、CBOは実行計画を作成し、その内容をPLAN TABLEに格納します。次に、DBMS_XPLAN.DISPLAY関数でPLAN TABLEの内容を出力することで、実行計画を確認できます。
前準備
EXPLAIN PLAN文を実行する前に、出力される実行計画を格納するPLAN TABLEを作成する必要があります。このPLAN TABLEの作成にはスクリプトが事前に用意されており、一般的なスクリプト名は「utlxplan.sql」と呼ばれます。正確なスクリプト名は使用する環境、OSによって異なります。
以下は、UNIXおよびLinux上でのスクリプト実行例です。SQL*Plusを用いてSYSDBA権限で接続し、実行します。
EXPLAIN PLAN文の実行
実際にEXPLAIN PLAN文を実行します。データベースに必要な権限をもつユーザーでログイン後、実行計画を確認するSQLの直前に、EXPLAIN PLAN FOR句を含めます。
EXPLAIN PLAN文は、SELECT、UPDATE、INSERT、DELETE文について、CBOが選択した実行計画を確認できます。この実行計画はCBOによって見積られたものであり、実際には実行されません。そのため、このコマンドを実行してもSQLはコミットされませんが、出力される実行計画は実際に実行した場合の実行計画と異なる可能性があります。
DBMS_XPLAN.DISPLAY関数の実行
最新のPLAN TABLEの内容を出力するには、DBMS_XPLAN.DISPLAY関数を使用します。
たとえば、以下のような結果が出力されます。この実行計画では、ハッシュ結合を行っていることがわかります。
実行計画の見方
それでは、出力された実行計画の見方について解説します。最初にご紹介した実行計画を例に解説していきます。
①SQL_ID
Oracleが自動的に付与するSQL文の識別子です。これが同じであれば同一SQLです。
②SQL
実際に解析したSQL文です。
③Plan Hash value
実行計画のハッシュ値です。これが同じであれば同一の実行計画です。
④-1 ツリー構造で表したステップ
SQLを実行するためにおこなう手順をステップごとに表示しています。ツリー構造の深いもの(つまり、右から)順に実行されます。このSQLでは、以下の流れです。
1.EMPLOYEES表に対してEMP_NAME_IX索引を使って索引スキャンで読み込み
2.DEPARTMENTS表に対してフルスキャン
3.2つの表をネステッドループ結合
④-2 統計情報
統計情報をもとに、各ステップの統計値を表示しています。左から対象レコード数、対象バイト数、コスト、実行時間が示されています。
⑤補足情報
検索条件などの補足情報です。
以上のように、実行計画を見れば、対象テーブルに対してどのようなステップを踏んで結果を出力しているかがわかります。1つのSQLの中でどのテーブルの読み込みで時間がかかっているのか、索引がつかわれているかいないか、といったことが把握でき、パフォーマンス劣化の原因を突き止めるのに役立ちます。
実行計画のチューニング方法
SQLを実行したもののパフォーマンスが悪い場合には、SQLチューニングが必要です。SQLチューニングは、以下の流れで行います。
1.非効率なSQLを特定
2.前提条件の確認(統計情報は正しくとられているか)
3.実行計画を確認
4.実行計画の内容から、コストの高い処理を改善する
5.再度SQLを実行し、妥当な処理時間なら終了。そうでなければ別のチューニングを行う。
コストの高い処理を改善する方法としては、代表的な例として以下があります。
・結合順序、結合方法を変更する。
・効率がよくなる索引を作成する
・SQLそのものを変更する
・ヒント句を使用し、アクセスパスを意図したパスに変更する
なお、Oracleの場合はSQLチューニング・アドバイザなど、SQLチューニングに役立つツールが実装されているため、それらをつかってSQLチューニングを行うとよいでしょう。ただし、ツールによってはオプション・ライセンスが必要となるものもあるため、ご注意ください。
まとめ
本記事では、データベースがSQLを具体的に処理する内容を示す実行計画について解説いたしました。同じ結果を表示するSQLでも、実行計画が異なればパフォーマンスが大きく変わります。
オプティマイザ統計が適切であるにもかかわらずSQLが非効率な場合は、実行計画を取得し確認することがパフォーマンスチューニングの第一歩です。
効率のよいSQLを実行するためにも、実行計画の内容を正しく理解しましょう。
- カテゴリ:
- キーワード: