Oracle DB ベストプラクティス
SQLの識別子 – SQL_ID, HASH_VALUE, OLD_HASH_VALUE
SQLの問題調査においては、”SELECT * FROM … ” といったSQLコマンド文字列だけではなく、SQLの識別子を抑えることが重要です。
SQLコマンド文字列だけでは、調査を効率的に進めることが難しい場合があるためです。SQLコマンド文字列は単なる文字列であるため、似たSQLコマンドを混同したり、大量のSQLが記録されたトレースファイルなどの診断情報から、目的のSQLを探しだすことに時間を要する恐れがあります。
しかし、Oracle Databaseはバージョンによって使用できるSQLの識別子が違ったり、識別子の算出ロジックが異なりますので、注意が必要です。
01.SQL識別子の確認方法
SQLの識別子を確認する一般的な方法は以下の5つです。
- V$SQLビュー – 共有プールにキャッシュされた共有カーソルに対応するSQLの識別子を確認
- V$SESSIONビュー – 実行中SQLと直前に実行していたSQLの識別子を確認
- SQLトレース – トレース有効時に実行したSQLの識別子を確認
- Statspackレポート – 高負荷SQLとしてリストされたSQLの識別子を確認
- AWRレポート – 高負荷SQLとしてリストされたSQLの識別子を確認
02.Oracle DatabaseのバージョンとSQL識別子
Oracle Database 9.2以前では、SQLハッシュ値(V$SQLのHASH_VALUE列に対応)をSQLの識別子として原則的に使用していました。
しかし、ハッシュの精度に問題があったため、Oracle Database 10.1よりSQL ID(V$SQLのSQL_ID列に対応)が導入されました。
このような経緯があるため、バージョンによって使用できるSQL識別子が異なります。
それに加えて、情報ソースによって、どのSQL識別子を出力するかが異なります。
情報ソースと表示されるSQL識別子の対応を以下に示します。
情報ソース |
10.1- |
-9.2 |
V$SQL |
SQL_ID, HASH_VALUE, OLD_HASH_VALUE |
HASH_VALUE(=SQL_HASH_VALUE) |
V$SESSION |
SQL_ID, SQL_HASH_VALUE |
SQL_HASH_VALUE |
SQLトレース |
SQL_HASH_VALUE, SQL_ID(11.1-) |
SQL_HASH_VALUE |
Statspackレポート |
OLD_HASH_VALUE |
SQL_HASH_VALUE |
AWRレポート |
SQL_ID |
N/A |
OLD_HASH_VALUEについては次で説明します。
03.10.1以降のOLD_HASH_VALUEとHASH_VALUE
Oracle Database 10.1 よりSQL_IDが導入されましたが、9.2以前で使用されていたSQLハッシュ値が使用される場合もあります。あるシステムをアップグレードした場合など、同一のSQLについてOracle Database9.2以前とOracle Datbase 10.1以降を比較する機会はあります。このため、Oracle Database 10.1以後でもSQLハッシュ値は残されています。
しかし、理由は不明ですが、V$SQLのHASH_VALUEで確認できるハッシュ値の算出アルゴリズムに変更が加えられました。このため、同一のSQLを9.2以前と10.1以降で実行した場合、HASH_VALUEが違った値になってしまいます。これでは、SQLの同一性の確認に使用できない為、9.2以前の算出アルゴリズムを使用した列として、OLD_HASH_VALUEが導入されています。
上記の表のとおり、10.1以降のStatspackレポートでは、SQLの識別子としてOLD_HASH_VALUEを出力しています。これは9.2以前のStatspackレポートと突合せできるようにするためです。
04.V$SQLよりSQLの識別子を確認する例
調査対象のSQLを実行した後、以下のようなSQLを実行することで、SQLの識別子を確認できます。
なお、共有カーソルから共有カーソルがage-outされた場合は、SQLの識別子を確認できないことに注意してください。
SQL> select sql_text, sql_id, hash_value, old_hash_value from v$sql where sql_text = 'select * from dual';
SQL_TEXT
--------------------------------------------------------------------------------
SQL_ID HASH_VALUE OLD_HASH_VALUE
------------- ---------- --------------
select * from dual
a5ks9fhw2v9s1 942515969 1333943659