sql >> データベース >  >> RDS >> Oracle

GTTテーブル統計とSYS.WRI$_OPTSTAT_TAB_HISTORY

    2015年に、Oracle 11.2.0.4データベースを12.1.0.2にアップグレードし、GTTの使用に関連するいくつかのパフォーマンスの問題が発生しました。私はここでそれらの問題についてブログを書きました。

    私が解決しようとしていた問題の核心は、12cでの動作の変更により、Oracleが統計を保存し、GTTには行がないのに行がゼロになるということでした。行数がゼロに等しいことを示す統計は、GTTを含むクエリで全表スキャンとデカルト積につながります。そのブログ投稿で述べたように、テーブルにデータを入力した後、DBMS_STATS.SET_TABLE_STATSを使用して、各セッションがより適切な実行プランに到達するための適切な統計情報を持つようにしました。

    Oracle 19cにアップグレードした後、GTTに関連する他のパフォーマンスの問題が発生し始めました。 GTTを使用したクエリは、「cursor pin:SwaitonX」待機イベントの待機を開始しました。これは、新しいOracleバージョンでの動作の変更である可能性がありますが、開発者がコードでGTTをより頻繁に使用しており、新しいバージョンとは関係がない可能性もあります。

    カーソルピン待機イベントに関連するクエリの場合、共有プールにSQLステートメントのバージョンが多数あることに気付きました。 V $ SQL_SHARED_CURSORを照会したところ、これらのSQLステートメントのPURGED_CURSOR =’Y’であることがわかりました。カーソルが無効になります。

    この問題を調査したところ、DBMS_STATS.SET_TABLE_STATSを呼び出してGTTのセッションベースの統計を取得するたびに、そのGTTを使用するすべてのSQLステートメントが無効になることがわかりました。したがって、待機します。待ち時間は長くなかったため、多くのエンドユーザーは問題に気付くことさえありませんでした。

    しかし、その後、新たな問題が発生しました。 SET_TABLE_STATSを呼び出すと、OracleはSYS.WRI $ _OPTSTAT_TAB_HISTORYにエントリを書き込み、セッションがテーブルの統計に設定した値を確認できます。デフォルトでは、このテーブルには30日間の履歴が保存されます。テーブルは非常に大きく成長し、SYSAUXのほとんどを消費していました。時々(毎時?)Oracleは30日以上前のエントリを削除します。このテーブルのこの定期的なプルーニングは、エンドユーザーのパフォーマンスに悪影響を及ぼしていました。以下は、このテーブルのプルーニングの影響を示すLightyのパフォーマンスグラフです。

    その恐ろしい赤い色はすべて、古い行がSYS.WRI$_OPTSTAT_TAB_HISTORYから削除されていたときです。

    そのため、5年前の私のパフォーマンスの「修正」により、別のパフォーマンスの問題が発生しました。パフォーマンスを向上させるために、GTTで共有統計を作成し、セッション統計の使用を停止しました。手順は次のとおりです。

    --set prefs to SHARED globally      
    exec DBMS_STATS.set_global_prefs ( pname => 'GLOBAL_TEMP_TABLE_STATS', pvalue => 'SHARED');
    --set the table and index stats
    exec dbms_stats.set_table_stats(ownname=>'MY_SCHEMA',tabname=>'MY_GTT_TABLE',numrows=>1000,numblks=>2,avgrlen=>15);
    exec dbms_stats.set_index_stats(ownname=>'MY_SCHEMA',indname=>'GTT_INDEX',indlevel=>1,numlblks=>2,numdist=>15,clstfct=>28,numrows=>1000);
    -- set prefs back to SESSION
    exec DBMS_STATS.set_global_prefs ( pname => 'GLOBAL_TEMP_TABLE_STATS', pvalue => 'SESSION');
    -- verify stats set
    select num_rows,blocks,last_analyzed,scope
    from dba_tab_statistics
    where table_name ='MY_GTT_TABLE';
    select blevel,leaf_blocks,distinct_keys,num_rows,clustering_factor,last_analyzed,scope
    from dba_ind_statistics
    where index_name='GTT_INDEX' and owner='MY_SCHEMA';

    共有統計が配置されたら、DBMS_SET_TABLE_STATSへの呼び出しをコードから削除します。


    1. SQL Serverデータベース内のすべてのID列を一覧表示します:sys.identity_columns

    2. ORA-16789:スタンバイREDOログが正しく構成されていません

    3. mysqlでグローバルsql_modeを設定する

    4. ローリング日付範囲内の個別の値の数を照会します