「なぜ、あのSQLは遅いのか」を正しく的確に調査する方法:しばちょう先生の試して納得! DBAへの道(改)(2)(2/3 ページ)
データベース技術や知識は、座学だけでなく「実際に手を動かして、実際に試して」理解を深めよう──。日本オラクルのデータベーススペシャリストが「新人をDBAに育てる際に使用する課題」をベースに、DBAがすぐ実践できる即効テクニックを紹介。今回は「“SQLの実行計画と処理時間の関係”の後編」を解説します。
演習3:SQLの実行計画の取得(2) 「explain plan for」での実行計画の取得方法も確認する
続いて「set autotrace」と並んでよく使われる、「explain plan for」を使った実行計画の取得方法も確認しましょう。
$ sqlplus TRY/TRY12345 SQL> explain plan for select * from TBL2 where col1 = 10000; 解析されました。 SQL> @?/rdbms/admin/utlxpls PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------- Plan hash value: 1207070705 -------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 65 | 3 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TBL2 | 1 | 65 | 3 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | PK_TBL2_COL1 | 1 | | 2 (0)| 00:00:01 | -------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("COL1"=10000)
ここでは、実行計画を取得したいSQL文を「explain plan for」に続けて記述します。そのSQL文は、SELECT文でもDML文でも実際には実行されず、実行計画だけを取得できます。このコマンドは現場でも意外と重宝するので、ぜひ覚えておいてください。ただし注意点が2つあります。
1つ目は「バインド変数を含んだSQL文では、実際と異なる実行計画を出力することがある」ことです。バインド変数を含むSQL文の実行計画を確認したい場合には、以降の演習で紹介予定の「dbms_xplan.display_cursor」ファンクションを使用することをお勧めします。
2つ目は、パフォーマンスのトラブルが発生した“後”で「set autotrace」や「explain plan for」で実行計画を取得しても、それは「トラブルが発生した際の実行計画ではない」可能性があることです。set autotraceやexplain plan forは、実行したその時点での実行計画なので、データベースの状態、正確には統計情報が変化しているかもしれません。この場合には、「dbms_xplan.display_cursor」ファンクションで解決可能です。まさにトラブル発生時の実行計画を取得できます。
演習4:同じ「全レコードの総数集計」でも実行時間が違う理由を理解する
では、「TBL2」表と「TBL3」表から、それぞれ「全レコードの総数を集計する実行時間」を測定してみましょう。
sqlplus /nolog SQL> connect / as sysdba alter system FLUSH BUFFER_CACHE; connect TRY/TRY set timing on select count(*) from TBL2; COUNT(*) ---------- 1000000 経過: 00:00:02.61 connect / as sysdba alter system FLUSH BUFFER_CACHE; connect TRY/TRY set timing on select count(*) from TBL3; COUNT(*) ---------- 1000000 経過: 00:00:10.58
あれ? なぜだ? と思っていただきたい演習です。TBL2表とTBL3表は同じ100万行のレコードが格納されているので、2つのSELECT文の結果もキッチリと100万となっています。全レコードへアクセスしているのだから、全表検索(実行計画では「TABLE ACCESS FULL」)だと推測されますが、なぜここまで実行時間に差が出てしまうのでしょうか。
この理由を追究するのが、現場のトラブルシューティングでも非常に重宝する実行計画の取得方法である、「dbms_xplan.display_cursor」ファンクションを使うことです。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- 【Oracle Database】忘れていませんか? 「アラートログ調査」に必要な、たった3つのキホン
データベース管理システムの運用でトラブルが発生したらどうするか。データベースサポートスペシャリストが現場目線の解決Tipsをお届けします。今回は基本編として「アラートログの調査で押さえるべき3つのポイント」を解説します。【Oracle Database 12c対応版】 - 障害発生! 問題切り分けはスピード勝負
Oracleデータベースの運用管理者は、突発的に直面するパフォーマンス障害にどうやって対処したらよいか。本連載は、非常に複雑なOracleのアーキテクチャに頭を悩ます管理者に向け、短時間で問題を切り分け、対処法を見つけるノウハウを紹介する。対象とするバージョンはOracle8から9iまでを基本とし、10gの情報は随時加えていく。(編集局) - パフォーマンス向上の最短コースを知る
本連載では、Oracleデータベースのパフォーマンス・チューニングの中から、特にSQLのチューニングに注目して、実践レベルの手法を解説する。読者はOracleデータベースのアーキテクチャを理解し、運用管理の実務経験を積んでいることが望ましい。対象とするバージョンは現状広く使われているOracle9iの機能を基本とするが、Oracle 10gで有効な情報も随時紹介していく。(編集局) - SQL実践講座
SQLは、データを操作するために非常に簡単な構文で構成されているように見えます。ところが実際に使い込んでいくと、一見簡単に取得できるように見えるデータが取得できない場面にぶち当たることもあります。こういった場面のために、SQLの効率的な使い方をエッセンスにしてお伝えします。