web-dev-qa-db-ja.com

Oracle 12cでall_constraintsのクエリを調整する方法

約8秒かかるため、次のクエリを調整する方法:

select constraint_name,table_name
                from  all_constraints 
         where  r_constraint_name in
                               (select  constraint_name
                                  from  all_constraints
                                where table_name='SUPPLIER');

SUPPLIERはテーブル名の例です。

6
Sameer Pradhan

多くの場合、RULEヒントはディクショナリビューをクエリするときに役立ちます。

select /*+ RULE */ constraint_name,table_name
                from  all_constraints 
         where  r_constraint_name in
                               (select  constraint_name
                                  from  all_constraints
                                where table_name='SUPPLIER');

しかし、クエリは正確ではありません。オブジェクトにも所有者がいます。

select /*+ RULE */ owner, constraint_name,table_name
                from  all_constraints 
         where  (r_owner, r_constraint_name) in
                               (select  owner,constraint_name
                                  from  all_constraints
                                where table_name='SUPPLIER'
                                      and owner='SOMEONE');

ただし、このクエリは結合として定式化できます。

select /*+ RULE +*/ ref.owner, ref.constraint_name,ref.table_name
  from  all_constraints ref, all_constraints cons
  where ref.r_constraint_name=cons.constraint_name
    and ref.r_owner=cons.owner
    and cons.owner='&OWNER'
    and cons.table_name='&TABLE';

最新のJOIN構文を使用する場合

select /*+ RULE */ ref.owner, ref.constraint_name,ref.table_name
  from  all_constraints ref JOIN all_constraints cons 
    on (ref.r_owner=cons.owner and ref.r_constraint_name=cons.constraint_name)
  where 
  cons.owner='&OWNER'
  and cons.table_name='&TABLE';

12cデータベース(12.1.0.2.0)のRULEヒントがある場合とない場合のタイミング結果をいくつか示します

SQL> alter system flush shared_pool;     

System altered.

Elapsed: 00:00:00.44
SQL> select ref.owner, ref.constraint_name,ref.table_name
  2    from  all_constraints ref, all_constraints cons
  3    where ref.r_constraint_name=cons.constraint_name
  4    and ref.r_owner=cons.owner
  5    and cons.owner='OWNER'
  6    and cons.table_name='TABLE';

no rows selected

Elapsed: 00:00:03.95
SQL> select ref.owner, ref.constraint_name,ref.table_name
  2    from  all_constraints ref, all_constraints cons
  3    where ref.r_constraint_name=cons.constraint_name
  4    and ref.r_owner=cons.owner
  5    and cons.owner='OWNER'
  6    and cons.table_name='TABLE';

no rows selected

Elapsed: 00:00:00.00
SQL> alter system flush shared_pool;   

System altered.

Elapsed: 00:00:00.02
SQL> select ref.owner, ref.constraint_name,ref.table_name
  2    from  all_constraints ref, all_constraints cons
  3    where ref.r_constraint_name=cons.constraint_name
  4    and ref.r_owner=cons.owner
  5    and cons.owner='OWNER'
  6    and cons.table_name='TABLE';

no rows selected

Elapsed: 00:00:03.94
SQL> alter system flush shared_pool;

System altered.

Elapsed: 00:00:00.01
SQL> select /*+ RULE */ ref.owner, ref.constraint_name,ref.table_name
  2    from  all_constraints ref, all_constraints cons
  3    where ref.r_constraint_name=cons.constraint_name
  4    and ref.r_owner=cons.owner
  5    and cons.owner='OWNER'
  6    and cons.table_name='TABLE';

no rows selected

Elapsed: 00:00:00.27
SQL> select /*+ RULE */ ref.owner, ref.constraint_name,ref.table_name
  2    from  all_constraints ref, all_constraints cons
  3    where ref.r_constraint_name=cons.constraint_name
  4    and ref.r_owner=cons.owner
  5    and cons.owner='OWNER'
  6    and cons.table_name='TABLE';

no rows selected

Elapsed: 00:00:00.16

私はまた、SYSオブジェクトの統計を収集しました

SQL> exec dbms_stats.gather_schema_stats('SYS',options=>'GATHER', -
> estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, -
> method_opt => 'FOR ALL COLUMNS SIZE AUTO', cascade => TRUE);

PL/SQL procedure successfully completed.

Elapsed: 00:03:41.58

しかし、それは助けにはなりませんでした。

11gシステム(11.2.0.4.0)では、ヒントなしのクエリははるかに優れていますが、ヒントがあってもクエリは高速化されます

SQL> alter system flush shared_pool;

System altered.

Elapsed: 00:00:00.01
SQL> select  ref.owner, ref.constraint_name,ref.table_name
  2    from  all_constraints ref, all_constraints cons
  3    where ref.r_constraint_name=cons.constraint_name
  4    and ref.r_owner=cons.owner
  5    and cons.owner='OWNER'
  6    and cons.table_name='TABLE';

no rows selected

Elapsed: 00:00:00.65
SQL> alter system flush shared_pool;

System altered.

Elapsed: 00:00:00.01
SQL> select  ref.owner, ref.constraint_name,ref.table_name
  2    from  all_constraints ref, all_constraints cons
  3    where ref.r_constraint_name=cons.constraint_name
  4    and ref.r_owner=cons.owner
  5    and cons.owner='OWNER'
  6    and cons.table_name='TABLE';

no rows selected

Elapsed: 00:00:00.66
SQL> alter system flush shared_pool;

System altered.

Elapsed: 00:00:00.01
SQL> select /*+ RULE */ ref.owner, ref.constraint_name,ref.table_name
  2    from  all_constraints ref, all_constraints cons
  3    where ref.r_constraint_name=cons.constraint_name
  4    and ref.r_owner=cons.owner
  5    and cons.owner='OWNER'
  6    and cons.table_name='TABLE';

no rows selected

Elapsed: 00:00:00.18
SQL> 
10
miracle173