5

JDBC 経由で Oracle DB を作成するアプリケーションを保守しています。今日からこのクエリを開始します。

SELECT  NULL                                                   AS pktable_cat  ,
        p.owner                                                AS pktable_schem,
        p.table_name                                           AS pktable_name ,
        pc.column_name                                         AS pkcolumn_name,
        NULL                                                   AS fktable_cat  ,
        f.owner                                                AS fktable_schem,
        f.table_name                                           AS fktable_name ,
        fc.column_name                                         AS fkcolumn_name,
        fc.position                                            AS key_seq      ,
        NULL                                                   AS update_rule  ,
        DECODE (f.delete_rule, 'CASCADE', 0, 'SET NULL', 2, 1) AS delete_rule  ,
        f.constraint_name                                      AS fk_name      ,
        p.constraint_name                                      AS pk_name      ,
        DECODE(f.deferrable, 'DEFERRABLE',5 ,'NOT DEFERRABLE',7 , 'DEFERRED', 6 ) deferrability
FROM    all_cons_columns pc,
        all_constraints p  ,
        all_cons_columns fc,
        all_constraints f
WHERE   1                      = 1
        AND p.table_name       = :1
        AND p.owner            = :3
        AND f.constraint_type  = 'R'
        AND p.owner            = f.r_owner
        AND p.constraint_name  = f.r_constraint_name
        AND p.constraint_type  = 'P'
        AND pc.owner           = p.owner
        AND pc.constraint_name = p.constraint_name
        AND pc.table_name      = p.table_name
        AND fc.owner           = f.owner
        AND fc.constraint_name = f.constraint_name
        AND fc.table_name      = f.table_name
        AND fc.position        = pc.position
ORDER BY fktable_schem,
        fktable_name  ,
        key_seq

私のすべてのブランチで同じように見えるため、一部のオラクルの内部が原因で非常に遅くなり始めました。

誰かが考えられる理由とこれに直面する方法を知っていますか?

よろしく、 ヌンツィオ

4

5 に答える 5

2

問題のクエリは、指定されたテーブルを参照する外部キーを列挙java.sql.DatabaseMetaData.getExportedKeys()するために委任する呼び出しによって生成されます。oracle.jdbc.OracleDatabaseMetaData.getExportedKeys()

@Jon の回答で述べたように、Oracle は、統計を収集することによって回避できる場合とできない場合がある、このクエリに対して最適ではない計画を使用することがあります。

コードを変更できる場合のその他の代替手段:

2 番目のオプションは、古いバージョンを呼び出していたLiquibaseプロジェクトによって選択されました。新しいバージョンは、 CORE-1844DatabaseMetaDataからの適切な結合で最適化されたクエリを使用します:

SELECT NULL AS pktable_cat, p.owner as pktable_schem, 
    p.table_name as pktable_name, pc.column_name as pkcolumn_name,    
    NULL as fktable_cat, f.owner as fktable_schem, f.table_name as fktable_name,    
    fc.column_name as fkcolumn_name, fc.position as key_seq, NULL as update_rule,    
    decode (f.delete_rule, 'CASCADE', 0, 'SET NULL', 2, 1) as delete_rule,    
    f.constraint_name as fk_name, p.constraint_name as pk_name,    
    decode(f.deferrable, 'DEFERRABLE', 5, 'NOT DEFERRABLE', 7, 'DEFERRED', 6) deferrability  
FROM    all_constraints p
INNER JOIN  all_cons_columns pc ON pc.owner = p.owner    
    AND pc.constraint_name = p.constraint_name    
    AND pc.table_name = p.table_name    
INNER JOIN all_constraints f ON p.owner = f.r_owner    
    AND p.constraint_name = f.r_constraint_name
INNER JOIN all_cons_columns fc ON fc.owner = f.owner    
    AND fc.constraint_name = f.constraint_name
    AND fc.table_name = f.table_name
    AND fc.position = pc.position
WHERE p.owner = :jdbcSchemaName
    AND p.constraint_type in ('P', 'U')    
    AND f.constraint_type = 'R'    
ORDER BY fktable_schem, fktable_name, key_seq
于 2015-12-03T15:41:16.573 に答える
1

チートするこの方法を見つけました.スキーマをリバースエンジニアリングする前に、jdbcに接続するユーザーとしてこれを実行します..

CREATE TABLE all_constraints AS
  SELECT owner,
         constraint_name,
         constraint_type,
         table_name,
         r_owner,
         r_constraint_name,
         delete_rule,
         status,
         deferrable,
         deferred,
         validated,
         generated,
         bad,
         rely,
         last_change,
         index_owner,
         index_name,
         invalid,
         view_related
  FROM   all_constraints;

CREATE TABLE all_cons_columns AS
  SELECT *
  FROM   all_cons_columns;

CREATE INDEX ac1
  ON all_constraints (owner, constraint_name, table_name);

CREATE INDEX acc1
  ON all_cons_columns (owner, constraint_name, table_name);  

次に、問題のクエリが本当に悲鳴を上げます..欠点は、時々それを更新する必要があることです..多分それを具体化されたビューにしますか?

于 2014-03-21T13:04:04.383 に答える
0
  1. oracle EXPLAIN PLAN http://docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm を使用します (結果を使用してボトルネックを見つけ、クエリを書き直すか変更して高速に実行します)。 ここに画像の説明を入力
  2. テーブルでインデックスを使用していることと、インデックスが更新されていることを確認してください。
  3. パーティショニングを使用します。
  4. 不要になったデータの一部をクリーンアップする
  5. 可能であれば hibernate を使用してください (これがレガシー アプリケーションの場合、これは簡単なことではないかもしれません)。これは、クエリを最適化し、JDBC クエリを記述する必要がないためです。
  6. 最後に、オラクルのパフォーマンス チューニングに関するドキュメントhttp://docs.oracle.com/cd/E11882_01/server.112/e41573/perf_overview.htm#PFGRF02503をご覧ください。
于 2014-02-18T16:41:14.333 に答える