web-dev-qa-db-ja.com

last_analyzedおよびstale_statsがnullの場合の意味

現在、Oracle 11gを実行しています。大量のインポート後に統計を実行する必要があるかどうかを調査しています。 statistics_levelが「TYPICAL」に設定されています。これに基づいて、統計を更新する必要はないと考えています。

Oracle Database 11g以降、MONITORINGおよびNOMONITORINGキーワードは非推奨になり、統計は自動的に収集されます。

https://docs.Oracle.com/cd/B28359_01/server.111/b28310/tables005.htm

ただし、データベースを作成して控えめなインポート(少数のテーブルに数十万から数百万のレコードを作成し、いくつかのインデックスを作成)を実行した後、インポートの影響を受けるすべてのテーブルで、クエリを使用したlast_analyzedおよびstale_statsにnullが表示されます未満。

select 
    table_name, 
    stale_stats, 
    last_analyzed
from 
    dba_tab_statistics
 where 
    owner = 'MY_SCHEMA'
order by 
    last_analyzed desc, table_name asc
;

この状態では、特定のクエリのパフォーマンスが低下すると思いますか?

統計が最終的に実行され、last_analyzedとstale_statsが最終的に入力されることを期待する必要がありますか(ドキュメントでは、これらの値はデフォルトで約3時間ごとに更新されることを示唆しています)?

中程度のサイズのデータ​​ベース(数百万のレコードと数千万のレコードを持つテーブル)の場合、統計をいじくる必要はなく、一般に、解決するよりも多くの問題が発生するというのが私の経験です。これは一般的にそうですか?

* * *当社の解決策に関する注記* * *

私たちはこれを使っていました:

analyze table my_table compute statistics

これに切り替えました:

dbms_stats.gather_table_stats('MY_SCHEMA', 'MY_TABLE');

分析テーブルステートメントは、1つの環境では約1:30分、2番目の環境では約15:00〜20:00分かかりました。

調査できた2つのインスタンスの両方で、gather_table_statsステートメントは約0:30〜1:00分かかりました。

今後の計画は、analyze tableステートメントをcollect_table_stats呼び出しに切り替えることです。

4
John

STATISTICS_LEVELとテーブル/インデックス統計の収集はまったく異なります。 STATISTICS_LEVELは、コマンドの実行中に行ソースの統計が収集されるかどうかに影響します。したがって、ディスプレイカーソルの各ステップのオプティマイザの推定値と実際の値を比較できます。

したがって、テーブル/インデックス統計は実行プランの最適化に使用され、STATISTICS_LEVELは実行プランが実行されているときに実行統計を収集するために使用されます。

last_analyzedがnullの場合は、テーブル統計がまだ収集されていないことを意味します。

stale_statsは、統計情報が新しいか古いか、または統計情報が次回自動的に収集されるかどうかを示します。デフォルト設定は10%です。テーブル統計を収集してから、行の10%未満の挿入/更新/削除を行った場合、統計は新しいと見なされます。変更された行の10%に達すると、それらは古くなります。

デフォルトでは、Oracleは、データベースの作成時に自動的に構成されるメンテナンス期間中に、テーブル/インデックスの統計を自動的に収集します。特定の要件がある場合は、通常、DBAによって再構成されます。

STATISTICS_LEVELについては、デフォルト値TYPICALは次のようになります。

HUSQVIK@hq_pdb_tcp> select * from dual;

D
-
X
HUSQVIK@hq_pdb_tcp> SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------
SQL_ID  a5ks9fhw2v9s1, child number 0
-------------------------------------
select * from dual

Plan hash value: 272002086

-------------------------------------------
| Id  | Operation         | Name | E-Rows |
-------------------------------------------
|   0 | SELECT STATEMENT  |      |        |
|   1 |  TABLE ACCESS FULL| DUAL |      1 |
-------------------------------------------

Note
-----
   - Warning: basic plan statistics not available. These are only collected when:
       * hint 'gather_plan_statistics' is used for the statement or
       * parameter 'statistics_level' is set to 'ALL', at session or system level

推定された行数を超えるものは表示されません。 ALTER SESSION SET statistics_level = ALLを設定すると、

HUSQVIK@hq_pdb_tcp> ALTER SESSION SET statistics_level = ALL;
HUSQVIK@hq_pdb_tcp> select * from dual;

D
-
X
HUSQVIK@hq_pdb_tcp> SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------
SQL_ID  a5ks9fhw2v9s1, child number 1
-------------------------------------
select * from dual

Plan hash value: 272002086

------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |      1 |00:00:00.01 |       3 |
|   1 |  TABLE ACCESS FULL| DUAL |      1 |      1 |      1 |00:00:00.01 |       3 |
------------------------------------------------------------------------------------

これで、各ステップの実行にかかった実際の行数と時間、および一貫した読み取り(バッファー列)の数も確認できます。

より複雑なクエリを使用すると、これよりもはるかに多くの情報を取得できます。 https://docs.Oracle.com/database/121/ARPLS/d_xplan.htm にあるドキュメントを確認してください。

また、統計のサンプリングはすべての行で行われるのではなく、デフォルトでは128行ごとに行われることにも注意してください(文書化されていない_rowsource_statistics_sampfreqパラメータを使用して変更できます)

4
Husqvik

(Husqvikは列とパラメーターの意味を完全に説明しました。この回答は統計の収集方法のみを扱います。)

統計は、重要なものの後に手動で収集する必要があります* テーブルに変更します。 Oracleには、11g以降、優れたデフォルトの自動統計収集プロセスがあります。しかし、その新しいシステムを使用しても、統計を手動で収集する理由は少なくとも2つあります。デフォルトの統計収集自動タスクは通常、ゆっくり変化するOLTPテーブル用であり、速く変化するデータウェアハウステーブル用ではありません。

  1. 重要なデータ変更は、重大なパフォーマンスの問題を簡単に引き起こす可能性があります。ロードされた直後にテーブルが使用される場合は、すぐに適切な統計が必要です。

    ETLプロセスの一般的な問題は、テーブルが1行から100万行になる場合です。オプティマイザは、大きなテーブルにはまだ1行しかないと考え、ハッシュ結合の代わりにネストされたループ結合を多数使用します。これらのアルゴリズムは、さまざまなコンテキストでうまく機能します。適切な統計がないと、Oracleは正しいコンテキストを知りません。

    NULL LAST_ANALYZEDは最悪のシナリオではありません。統計がない場合、Oracleは動的サンプリングを使用して迅速な統計推定を生成します。最悪のケースは、統計ジョブが昨夜、テーブルが空のときに実行された場合です。オラクルは、実際にはそうではないのに、良い統計があると考えています。

  2. 統計の自動タスクは、大きな変更に対応できない場合があります。統計の自動タスクは、優先度の低いシングルスレッドプロセスです。自動プロセスに残された大きなテーブルが多すぎると、メンテナンスウィンドウ中にそれらを処理できない場合があります。


悪いニュースは、開発者がオプティマイザ統計を無視できないことです。 DBAは後でそれを処理することはできません。 Managing Optimizer Statistics など、マニュアルの章の一部を読むと役立つ場合があります。

グッズニュースは、Oracle 11gがついにニースのデフォルト設定を持つことです。通常、パラメータをいじる必要はありません。ほとんどの場合、従うべき単純なルールがあります。テーブルが大幅に変更された場合は、次のように実行します。

dbms_stats.gather_table_stats('SCHEMA_NAME', 'TABLE_NAME');

*:「有意」は主観的な言葉です。通常、変更は絶対的なものではなく、相対的なサイズの点で重要です。テーブルに現在1つの行がある場合は、100万行をテーブルに追加することは重要ですが、テーブルに10億行がある場合は重要ではありません。

1
Jon Heller