GAGA LIFE.

インフラエンジニアブログ

スポンサーリンク

データタイプANYDATAの参照方法

データタイプANYDATAの参照方法

概要

Oracle Databaseには複数のデータ型(VARCHAR2、NUMBER等々)のデータを格納することができるANYDATAという特殊なデータ型が存在しています。

Oracle Database PL/SQLパッケージおよびタイプ・リファレンス 19c 272 ANYDATAタイプ

ANYDATAタイプには、指定のタイプのインスタンスおよびそのタイプの説明が含まれています。つまり、ANYDATAは自己記述型です。ANYDATAは、データベースに永続的に格納できます。 

通常、テーブル設計・作成時に意図してこのデータ型を指定することはないと思いますが、SPA(SQL Performance Analyzer)などで利用するSTS(SQL Tuning Set)に格納されたバインド変数値で使用されていたりします。
そのため、バージョンアップ検証などでSPAを使用した際に確認対象のSQLで使用しているバインド変数値を確認したい場合などにはこのデータを参照するために特殊なアクセス・ファンクションを使う必要があります。

STS(SQL Tuning Set)とは

SPA(SQL Performance Analyzer)やアドバイザ等に対するINPUT情報として利用できます。
下記の情報を含むデータベース・オブジェクトです。

SQL文(SQLテキスト)
実行コンテキスト(スキーマ、アプリケーション・モジュール名、バインド変数など)
実行統計(実行時間、CPU時間、バッファ読み取り量、ディスク読み取り量など)
実行計画

このSTSの情報を各種ツールにかけて分析を実行します。

f:id:undercovergeek:20210109103403p:plain

ANYDATAの参照

STSに含めたバインド変数を使用したSQL

SQL_ID:1y431vxyc0xj7

variable var1 number;
variable var2 char(10);
variable var3 varchar2(10);
variable var4 varchar2(19);
execute :var1 := 1;
execute :var2 := 'a1';
execute :var3 := 'b1';
execute :var4 := '03-06-2010 18:00:00';
select * from tab1 
where col1 = :var1 and col2 = :var2 and col3= :var3
and col4 = to_date(:var4, 'DD-MM-YYYY HH24:MI:SS');

そのまま参照では見れない(「ANYDATA()」が返却される)

SQL> select SQL_ID,VALUE FROM ALL_SQLSET_BINDS WHERE SQL_ID='1y431vxyc0xj7';
SQL_ID                                  VALUE()
--------------------------------------- --------------------------------------------------
1y431vxyc0xj7                           ANYDATA()
1y431vxyc0xj7                           ANYDATA()
1y431vxyc0xj7                           ANYDATA()
1y431vxyc0xj7                           ANYDATA()

参照方法(ファンクションを使って参照)

GETTYPENAMEメンバー・ファンクションを使用してそれぞれキャストして返す(※キャラクタ型はそのままアクセスファンクション)

SQL> SELECT
  ANYDATA.GETTYPENAME(value) TYPE_NAME,
      CASE ANYDATA.GETTYPENAME(value)
        WHEN 'SYS.NUMBER'   THEN TO_CHAR(ANYDATA.ACCESSNUMBER(value))
        WHEN 'SYS.DATE'     THEN TO_CHAR(ANYDATA.ACCESSDATE(value))
        WHEN 'SYS.VARCHAR2' THEN ANYDATA.ACCESSVARCHAR2(value)
        WHEN 'SYS.CHAR'     THEN ANYDATA.ACCESSCHAR(value)
        ELSE NULL
      END AS DATA
FROM DBA_SQLSET_BINDS
WHERE SQL_ID = '1y431vxyc0xj7'
;
  2    3    4    5    6    7    8    9   10   11   12  
TYPE_NAME            DATA
-------------------- --------------------
SYS.NUMBER           1
SYS.CHAR             a1
SYS.VARCHAR2         b1
SYS.VARCHAR2         03-06-2010 18:00:00

バインド変数が確認できました。
今回参照した以外のデータ型も参考資料にあるアクセスファンクションで参照できます。

参考資料

Oracle Database PL/SQLパッケージおよびタイプ・リファレンス 19c
272 ANYDATAタイプ
https://docs.oracle.com/cd/F19136_01/arpls/ANYDATA-TYPE.html#GUID-08696B1A-5E92-45C6-89E9-00F934311797

ハードパースとソフトパース

概要

ハードパースとソフトパースについての解説

ハードパース

様々な実行計画を生成し、最適な実行計画を選択

  • 統計情報が収集済みのとき(ソフトパース)

      * 統計情報を利用   
      * 統計情報:表、列、索引、システム  
    
  • 統計がない時or古い時(ハードパース)

      * 動的サンプリングで収集した統計情報を利用  
    

f:id:undercovergeek:20201219103118p:plain

optimizer_dynamic_sampling

統計が不足している際、SQL実行時に自動的統計をサンプリング
サンプリングレベルを0-10で指定(0はOFF)

親カーソルと子カーソル

実行計画生成時、1つの親カーソルに対し、1つ以上の子カーソルが生成
f:id:undercovergeek:20201219103149p:plain

ハードパースの流れ

以前に実行されていない場合⇒ハードパース(実行計画を生成)
ディクショナリ・キャッシュを利用し、SQL文の構文や権限をチェック

共有プールの共有SQL領域を確保⇒実行計画を生成
f:id:undercovergeek:20201219103216p:plain

ソフトパース

共有SQL領域にキャッシュされている実行計画を利用
- オプティマイザや行ソースジェネレータによる処理が不要⇒CPU負荷の軽減
- 新たな共有SQL領域の確保が不要⇒メモリ使用量の低減
f:id:undercovergeek:20201219103307p:plain

ソフトパースの流れ

以前に実行されている場合⇒ソフトパース(実行計画を再利用)

共有SQL領域上にある以前の実行計画を再利用
f:id:undercovergeek:20201219103441p:plain

SQL文を実行した際のメモリ上の動作

概要

SQL文を実行した際のメモリ上の動作を説明

SQL実行時のメモリ上の動作

SQL文を発行した後、メモリ上では大きく以下のような流れとなる
1. SQLリクエストを受信

2. カーソルのオープン

3. 実行計画の生成/再利用

4. SQL文の実行

5. カーソルのクローズ
f:id:undercovergeek:20201212093016p:plain

カーソル:特定のプライベートSQL領域

  • SQL文は、共有SQL領域とプライベートSQL領域(カーソル)に格納される
  • 共有SQL領域は共有プールのライブラリキャッシュ内にあり、SQL文の解析ツリーと実行計画が格納される
  • プライベートSQL領域(カーソル)には以下の情報が格納される
    ・持続領域: バインド変数値が格納される
    ・ランタイム領域
    - 問合せ実行状況の情報: たとえば、全表スキャンの場合、この領域にはスキャンの進行情報が格納される  
    - SQL作業領域:ソートやハッシュ結合など、メモリー集中型の操作に必要な場合に割り当てられる  
    

    f:id:undercovergeek:20201212093050p:plain

実行計画生成

f:id:undercovergeek:20201212093127p:plain

実行計画生成の前提知識(SQL_ID/PLAN_HASH_VALUE/CURSOR)

概要

SQLや実行計画を解析する際の最低限知っておくべきと考える情報を記載します。

SQL_ID(SQL識別子)

意味

Oracleは実行されたSQL文を13桁の「文字列」で管理していますが、この文字列のことをSQL識別子(SQL_ID)と呼びます。

特徴

SQL識別子(SQL_ID)はSQLテキストに依存して作成されます。そのため、以下の特徴があります。

f:id:undercovergeek:20201205101450p:plain

その他

SQL_IDは、13文字の文字列で表される基数32の数字です。
各文字は数字または32の小文字のいずれかとなります。 ※例) ddzxfryd0uq9t

文字e、i、l、oは、転記エラーのリスクを制限するために使用されていません。
SQL_IDは、実際にはSQLステートメントの文字から生成されたハッシュ(MD5)です。
そのため、その大文字小文字と空白が保持されていると仮定すると、同じSQLステートメントは、使用されるすべてのデータベースで同じSQL_IDを持ちます。

PLAN_HASH_VALUE

意味

Oracleは実行計画も一意の識別子(識別番号)で管理していますが、この識別子のことをPLAN_HASH_VALUEと呼びます。

特徴

PLAN_HASH_VALUEは実行計画に依存して作成されます。
以下の特徴があります。

f:id:undercovergeek:20201205101636p:plain

その他

PLAN_HASH_VALUEが同一であれば同一の実行計画とみなせます。
例えば検証環境と本番環境のPLAN_HASH_VALUEが同一であれば、実行計画が同じと言えます。

カーソル

意味

SQLを実行すると、SQLがHard Parseされて実行計画が共有プールに格納されます。
共有プールに格納された、SQL文と実行計画のセットをカーソルと呼びます。
カーソルはV$SQLやその関連表に格納され、V$SQLの1レコードが1カーソルに対応します。

特徴

カーソルはスキーマや実行計画の違いを管理するために使用されます。
このため、ある1つのSQL文(SQL_ID)であっても複数のカーソルが存在する場合があります。
例:同じSQL文(SQL_ID)を別のスキーマで実行した場合、同一のSQL_IDに複数のカーソルが作成されます。
場合によっては同じSQL_IDであっても複数の実行計画ができる場合があります。

f:id:undercovergeek:20201205101753p:plain

SQL文や実行計画に関連するビュー

V$SQLAREA

V$SQLAREAは、共有SQL領域の統計情報を示し、SQL文字列ごとに1行ずつ表示します。
メモリー内にあり、解析済で、実行準備のできているSQL文に関する統計情報を提供します。

代表的な情報
  • 全ての子カーソルに関する情報
  • SHARABLE_MEM:カーソルが使用している共有メモリーの量。
  • 子カーソルが複数存在する場合の、すべての子カーソルに使用される、すべての共有メモリーの合計。
  • VERSION_COUNT:この親の下でキャッシュ内にある子カーソルの数
  • EXECUTIONS:すべての子カーソルについて、実行の合計数
  • PHYSICAL_READ_BYTES:監視対象のSQLによってディスクから読み取られたバイト数

V$SQL

V$SQLは、GROUP BY句のない共有SQL領域についての統計情報を示し、入力された元のSQLテキストの子カーソルごとに1行ずつ表示します。
V$SQLに表示される統計情報は、通常、問合せの実行が終了した時点で更新されます。
ただし、問合せの実行が長期にわたる場合は、5秒ごとに更新されます。
これによって、実行中に、長時間実行されるSQL文の影響を容易に確認できます。

代表的な情報
  • SQL_ID:ライブラリ・キャッシュ内の親カーソルのSQL識別子
  • 子カーソル固有の情報
  • 実行統計
  • ROWS_PROCESSED:解析されたSQL文が戻す行数の合計

V$SQL_PLAN

V$SQL_PLANは、ライブラリ・キャッシュにロードされる子カーソルごとの実行計画情報を示します。

V$SQLTEXT

V$SQLTEXTは、SGA内の共有SQLカーソルに属するSQL文のテキストを示します。

SQL_ID確認方法

f:id:undercovergeek:20201205101907p:plain

参考資料

Expert Oracle SQL
www.amazon.co.jp

Oracle 主要な待機イベント(RAC固有)

主な待機イベント一覧

Category Wait Class Event
RAC Cluster gc cr/current (multi block) request
Cluster gc cr/current grant 2-way
Cluster gc cr/current block 2-way/3-way
Cluster gc buffer busy acquire/release

インターコネクト

RACにはインターコネクトを通したデータのやり取りに関する待機イベントがある。 これらの待機イベントは大きく2種類に分けられる。
- GES(Global Enqueue Service)の待機イベント:インスタンス間の排他制御に関連
- GCS(Global Cache Service)の待機イベント:インスタンス間のバッファキャッシュ一貫性に関連
本記事ではGCSの説明を行う
ブロックを取得する際、ディスクと自ノードのバッファキャッシュ以外に他インスタンスのバッファキャッシュも取得先の選択肢となるため、ブロック取得の手続きがシングルインスタンスより複雑になる

GCS

  • バッファには以下の2種類がある
    • CURRENT:ブロックの最新バージョン(DML文で要求される)
    • CR(consistent read):特定時点のコミット済み変更が反映されたブロック(SELECTで要求される)

      GCS待機イベントは下記のように表示される

      f:id:undercovergeek:20200926113144p:plain

CURRENTとCRの違い

f:id:undercovergeek:20200926113233p:plain

gc cr/current (multi block) request

  • 意味
    CRブロックあるいはCURRENTブロックの要求中のためにサーバープロセスが待機していることを示す
  • 状況
    リクエストが完了し、正確な待機イベントが現れるまでの一時的な待機イベント(プレースホルダ)と位置付けられる f:id:undercovergeek:20200926113602p:plain

gc cr/current grant 2-way

  • 意味
    CRブロックあるいはCURRENTブロックの要求に対して、ディスクからの読込みが許可されたことを示す ※何らかの要因でこの許可に時間を要した場合は、gc cr/current grant busy待機イベントが発生する
  • 状況
    リソースマスターへの要求とサーバープロセスへの許可で2方向のやり取りを行う f:id:undercovergeek:20200926113624p:plain

gc cr/current block 2-way

  • 意味
    CRブロックあるいはCURRENTブロックの要求に対してキャッシュしているインスタンスからブロック転送が行われたことを示す
  • 状況
    リソースマスターへの要求とサーバープロセスへの転送で2方向のやり取りを行う f:id:undercovergeek:20200926113650p:plain

gc cr/current block 3-way

  • 意味
    CRブロックあるいはCURRENTブロックの要求に対してキャッシュしているインスタンスからブロック転送が行われたことを示す
  • 状況
    リソースマスターへの要求/ブロック保持ノードへの転送指示/サーバープロセスへの転送、の3方向のやり取りを行う f:id:undercovergeek:20200926113752p:plain

gc buffer busy acquire

  • 意味
    同一インスタンスの別セッションがキャッシュフュージョンによって他のキャッシュからバッファを読み取り終わるのをサーバープロセスが待機していることを示す
  • 状況
    同一ブロックの取得要求による競合によって発生する f:id:undercovergeek:20200926113816p:plain

gc buffer busy release

  • 意味
    別インスタンスの別セッションがキャッシュフュージョンによってローカルキャッシュからバッファを読み取り終わるのを待機していることを示す
  • 状況
    同一ブロックの取得要求による競合によって発生する f:id:undercovergeek:20200926113835p:plain

Oracle 主要な待機イベント

主な待機イベント一覧

Category Wait Class Event
I/O User I/O db file sequential read
User I/O db file scattered read
User I/O direct path read
Commit log file sync
System I/O db file parallel write
Memory Configuration free buffer waits
N/W Network SQL*Net more data to client

db file sequential read

  • 意味
    サーバープロセスがバッファキャッシュから単一ブロックを読み込む際にディスクからメモリデータが配置されるのを待機している状態を示す
  • 状況
    多くの場合、索引を経由したブロックの読込みを行っていることを意味する
    f:id:undercovergeek:20200922131944p:plain

db file scattered read

  • 意味
    サーバープロセスがバッファキャッシュから不連続な複数ブロックを読み込む際、ディスクからメモリへデータが配置されるのを待機している状態を示す
  • 状況
    多くの場合、表のフルスキャンや高速全索引スキャンによる読込みを行っていることを意味する
    f:id:undercovergeek:20200922132006p:plain

direct path read

  • 意味
    ディスクからPGAへの読込でサーバープロセスが待機していることを示す
  • 状況
    大規模表へのフルスキャンなどバッファキャッシュを経由しないブロック読込みを行っていることを意味する
    f:id:undercovergeek:20200922132025p:plain

log file sync

  • 意味
    LGWRプロセスがREDOログファイルへREDO情報の書込みを完了させることをサーバープロセスが待機していることを示す
  • 状況
    COMMIT、ROLL BACK発行時に発生する
    f:id:undercovergeek:20200922132044p:plain

db file parallel write

  • 意味
    ダーティバッファ(更新されたブロック)をディスクへ書き込むI/O処理が完了するのをDBWRn(データベースライター)が待機していることを示す
  • 状況
    チェックポイントなどDBWRnがバッファをディスクへ反映されるタイミングで発生する
    f:id:undercovergeek:20200922132105p:plain

free buffer waits

  • 意味
    利用可能なバッファが用意されるのをサーバープロセスが待機していることを示す
  • 状況
    サーバープロセスがデータベースバッファキャッシュ上に利用可能バッファを見つけられなかった際、DBWRnに書き出しを要求し、このイベントで待機する
    f:id:undercovergeek:20200922132124p:plain

SQL*Net more data to client

  • 意味
    結果セットをクライアントに返す際に送信が滞り、サーバープロセスが待機していることを示す
  • 状況
    結果セットの返信時、SDUのサイズを超えた時に発生する
    f:id:undercovergeek:20200922132142p:plain

スポンサーリンク