Oracleのパフォーマンス調整で重要な役割を果たした統計。 Oracle Optimizerは、SQLクエリに含まれるOracleテーブルの統計に基づいて実行プランを作成します。
たとえば、場合によっては、統計をoracleテーブルにロックしたい場合があります
- スケジュール統計ジョブでテーブルを分析したくないが、後で、またはより高い見積もりでテーブルを分析したい
- パフォーマンス上の理由から、テーブルの統計を生成したくない
- テーブルデータが変更されていないときにサーバーが統計の生成に時間を費やしたくない
統計をロックしたい場合はもっとたくさんあるかもしれません
目次
テーブルの統計をロックする方法
標準のOracleパッケージDBMS_STATSを使用して、テーブルの統計をロックできます
exec dbms_stats.lock_table_stats('table_owner','table_name'); Example
SELECT stattype_locked FROM dba_tab_statistics WHERE table_name = 'TEST' and owner = 'TECH';
STATTYPE_LOCKED
—–------------
exec dbms_stats.lock_table_stats('TEST','TECH');
SELECT stattype_locked FROM dba_tab_statistics WHERE table_name = 'TEST' and owner = 'TECH';
STATTYPE_LOCKED
—–--------
ALL
統計がロックされているテーブルを見つける方法
以下のクエリを使用して、統計がロックされているすべてのテーブルを見つけることができます
select owner, table_name, stattype_locked from dba_tab_statistics where stattype_locked is not null;
統計がロックされているテーブルで統計生成ジョブを実行する
統計がロックされているテーブルで統計の収集を実行しようとすると、 ORA-20005オブジェクトの統計がロックされています(stattype =all)
SQL> exec dbms_stats.gather_table_stats('TECH', 'TEST');
BEGIN dbms_stats.gather_table_stats('TECH', 'TEST'); END;
*
ERROR at line 1:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: at “SYS.DBMS_STATS”, line 10640
ORA-06512: at “SYS.DBMS_STATS”, line 10664
ORA-06512: at line 1
以下の手順を実行して、統計のロックを解除し、統計を生成して再度ロックすることができます
exec dbms_stats.unlock_table_stats('TECH','TEST');
exec dbms_stats.gather_table_stats('TECH', 'TEST');
exec dbms_stats.lock_table_stats('TECH','TEST');
or
exec dbms_stats.gather_table_stats('TECH', 'TEST',force=>true);
テーブルとスキーマの統計のロックを解除する方法/スキーマのテーブルの統計のロックを解除する
オブジェクトが見つかったら、以下のクエリを使用してオブジェクトのロックを解除できます
unlock table stats for schema
exec dbms_stats.unlock_schema_stats('schema_owner');
exec dbms_stats.unlock_table_stats('table_owner','table_name');
Example
exec dbms_stats.unlock_schema_stats('TECH');
exec dbms_stats.unlock_table_stats('TECH','TEST');
統計がテーブルにロックされた状態でのインデックスの作成
10g以降、インデックスを作成するたびに統計が自動的に生成されます。これで、この式が変わります。テーブルがロックされている場合、インデックスの作成中に統計は生成されません。ロックされたオブジェクトのインデックスを作成するときに統計を収集するには、FORCEオプションを使用する必要があります。例を見て、詳細を理解しましょう。
Example
Lets first create the dummy table and lock the statistics on that table
SQL> create table test as select a.* ,rownum id from all_objects a where rownum <1001;
SQL> exec dbms_stats.lock_table_stats('TECH','TEST');
Now we will try to create index
SQL> create index test_idx on test(id);
Index created.
SQL> select num_rows, last_analyzed from user_ind_statistics where index_name ='TEST_IDX';
NUM_ROWS LAST_ANAL
---------- ---------
So statistics on index is not generated automatically for the locked statistics table
Lets try to generate the statistics using DBMS_STATS
SQL> exec dbms_stats.gather_index_stats(null, 'TEST_IDX');
BEGIN dbms_stats.gather_index_stats(null, 'TEST_IDX'); END;
*
ERROR at line 1:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: at "SYS.DBMS_STATS", line 10640
ORA-06512: at "SYS.DBMS_STATS", line 10664
ORA-06512: at line 1
So statistics generation failed.
In order to generate stats on the index, We can use force option in dbms_stats to override this
SQL> exec dbms_stats.gather_index_stats(null, 'TEST_IDX',force=>true);
PL/SQL procedure successfully completed.
SQL> select num_rows, last_analyzed from user_ind_statistics where index_name ='IDX';
NUM_ROWS LAST_ANAL
---------- ---------
1000 01-SEP-17
Lets try to create a new index with compute statistics clause
SQL> create index TEST_IDX1 on test(object_name) compute statistics;
create index idx on test(object_name) compute statistics
*
ERROR at line 1:
ORA-38029: object statistics are locked
So ORA-38029 error happens, So we need to create index with out the compute statistics clause and then generate stats using force option
SQL> create index TEST_IDX1 on test(object_name);
SQL> exec dbms_stats.gather_index_stats(null, 'TEST_IDX1',force=>true);
Same things happens if we rebuild the index with compute statistics option
SQL> alter index TEST_IDX1 rebuild compute statistics;
alter index TEST_IDX1 rebuild compute statistics
*
ERROR at line 1:
ORA-38029: object statistics are locked
SQL> alter index TEST_IDX1 rebuild;
Index altered.
SQL> exec dbms_stats.gather_index_stats(null, 'TEST_IDX1',force=>true);
PL/SQL procedure successfully completed.
Oracleでテーブル統計をロック/ロック解除する方法に関する情報が気に入っていただければ幸いです。また、 ORA-20005:オブジェクト統計がロックされている場合の対処方法を知っておく必要があります。 およびORA-38029:オブジェクト統計 ロックされます
関連記事
リリース11iおよびR12での統計の収集
11gでの増分統計の収集
11gでのスキーマ統計の収集(FND_HISTOGRAM_COLS)のora-20001
Oracleでのテーブル監視の設定方法とSTATISTICS_LEVEL
Oracleチュートリアル:古い統計を確認する方法
Oracleオプティマイザーモード
統計に関するOracleドキュメント