3

添付のクエリについてアドバイスが必要です。クエリは 1 時間以上実行され、Explain Plan に従って完全なテーブル スキャンが行われます。私はクエリのチューニングにかなり慣れていないので、アドバイスをいただければ幸いです。まず、使用するすべての列にインデックスが作成されているにもかかわらず、完全なテーブル スキャンが行われるのはなぜですか。次に、実行時間を短縮できる可能性はありますか。アクセスされるすべてのテーブルは巨大で、何百万ものレコードが含まれています。それでも、いくつかのオプションを検討したいと思います。あなたの助けに感謝します。

クエリ:

select 
    distinct rtrim(a.cod_acct_no)||'|'||
    a.cod_prod||'|'||
    to_char(a.dat_acct_open,'Mon DD YYYY HH:MMAM')||'|'||
    a.cod_acct_title||'|'||
    a.cod_acct_stat||'|'||
    ltrim(to_char(a.amt_od_limit,'99999999999999999990.999999'))||'|'||
    ltrim(to_char(a.bal_book,'99999999999999999990.999999'))||'|'||
    a.flg_idd_auth||'|'||
    a.flg_mnt_status||'|'||
    rtrim(c.cod_acct_no)||'|'||
    c.cod_10||'|'||
    d.nam_branch||'|'||
    d.nam_cc_city||'|'||
    d.nam_cc_state||'|'||
    c.cod_1||'|'||
    c.cod_14||'|'||
    num_14||'|'||
    a.cod_cust||'|'||
    c.cod_last_mnt_chkrid||'|'||
    c.dat_last_mnt||'|'||
    c.ctr_updat_srlno||'|'||       
    c.cod_20||'|'||            
    c.num_16||'|'||
    c.cod_14||'|'||                
    c.num_10  ||'|'||
    a.flg_classif_reqd||'|'||

    (select g.cod_classif_plan_id||'|'||
     g.cod_classif_plan_id
     from
     ac_acct_preferences g 
     where 
     a.cod_acct_no=g.cod_acct_no AND g.FLG_MNT_STATUS = 'A' )||'|'||
    (select e.dat_cam_expiry from  flexprod_host.AC_ACCT_PLAN_CRITERIA e where  a.cod_acct_no=e.cod_acct_no   and e.FLG_MNT_STATUS ='A')||'|'||
    c.cod_23||'|'||
    lpad(trim(a.cod_cc_brn),4,0)||'|'||

    (select min( o.dat_eff)  from ch_acct_od_hist o where a.cod_acct_no=o.cod_acct_no )
from    
    ch_acct_mast a,

    ch_acct_cbr_codes c,
    ba_cc_brn_mast d

where 
    a.flg_mnt_status ='A'

    and c.flg_mnt_status ='A'
    and a.cod_acct_no= c.cod_acct_no(+)
    and a.cod_cc_brn=d.cod_cc_brn 

    and a.cod_prod in (
    299,200,804,863,202,256,814,232,182,844,279,830,802,833,864,
    813,862,178,205,801,235,897,231,187,229,847,164,868,805,207,
    250,837,274,253,831,893,201,809,846,819,820,845,811,843,285,
    894,284,817,832,278,818,810,181,826,867,825,848,871,866,895,
    770,806,827,835,838,881,853,188,816,293,298)

クエリ プラン:

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 4253465430

------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                       | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                            |   733K|   125M|       |   468K  (1)|999:59:59 |       |       |
|   1 |  TABLE ACCESS BY INDEX ROWID        | AC_ACCT_PREFERENCES        |     1 |    26 |       |     3   (0)| 00:01:05 |       |       |
|*  2 |   INDEX UNIQUE SCAN                 | IN_AC_ACCT_PREFERENCES_1   |     1 |       |       |     2   (0)| 00:00:43 |       |       |
|   3 |   PARTITION HASH SINGLE             |                            |     1 |    31 |       |     3   (0)| 00:01:05 |   KEY |   KEY |
|   4 |    TABLE ACCESS BY LOCAL INDEX ROWID| AC_ACCT_PLAN_CRITERIA      |     1 |    31 |       |     3   (0)| 00:01:05 |   KEY |   KEY |
|*  5 |     INDEX UNIQUE SCAN               | IN_AC_ACCT_PLAN_CRITERIA_1 |     1 |       |       |     2   (0)| 00:00:43 |   KEY |   KEY |
|   6 |     SORT AGGREGATE                  |                            |     1 |    29 |       |            |          |       |       |
|   7 |      FIRST ROW                      |                            |     1 |    29 |       |     3   (0)| 00:01:05 |       |       |
|*  8 |       INDEX RANGE SCAN (MIN/MAX)    | IN_CH_ACCT_OD_HIST_1       |     1 |    29 |       |     3   (0)| 00:01:05 |       |       |
|   9 |  HASH UNIQUE                        |                            |   733K|   125M|   139M|   468K  (1)|999:59:59 |       |       |
|* 10 |   HASH JOIN                         |                            |   733K|   125M|       |   439K  (1)|999:59:59 |       |       |
|* 11 |    TABLE ACCESS FULL                | BA_CC_BRN_MAST             |  3259 |   136K|       |    31   (0)| 00:11:04 |       |       |
|* 12 |    HASH JOIN                        |                            |   747K|    97M|    61M|   439K  (1)|999:59:59 |       |       |
|  13 |     PARTITION HASH ALL              |                            |   740K|    52M|       |   286K  (1)|999:59:59 |     1 |    64 |
|* 14 |      TABLE ACCESS FULL              | CH_ACCT_MAST               |   740K|    52M|       |   286K  (1)|999:59:59 |     1 |    64 |
|* 15 |     TABLE ACCESS FULL               | CH_ACCT_CBR_CODES          |  9154K|   541M|       |   117K  (1)|699:41:01 |       |       |
------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("COD_ACCT_NO"=:B1 AND "FLG_MNT_STATUS"='A' AND "COD_ENTITY_VPD"=TO_NUMBER(NVL(SYS_CONTEXT('CLIENTCONTEXT','entity_co
              de'),'0')))
   5 - access("COD_ACCT_NO"=:B1 AND "FLG_MNT_STATUS"='A' AND "COD_ENTITY_VPD"=TO_NUMBER(NVL(SYS_CONTEXT('CLIENTCONTEXT','entity_co
              de'),'0')))
   8 - access("COD_ACCT_NO"=:B1)
       filter("COD_ENTITY_VPD"=TO_NUMBER(NVL(SYS_CONTEXT('CLIENTCONTEXT','entity_code'),'0')))
  10 - access("COD_CC_BRN"="COD_CC_BRN")
  11 - filter("COD_ENTITY_VPD"=TO_NUMBER(NVL(SYS_CONTEXT('CLIENTCONTEXT','entity_code'),'0')))
  12 - access("COD_ACCT_NO"="COD_ACCT_NO")
  14 - filter(("COD_PROD"=164 OR "COD_PROD"=178 OR "COD_PROD"=181 OR "COD_PROD"=182 OR "COD_PROD"=187 OR "COD_PROD"=188 OR
              "COD_PROD"=200 OR "COD_PROD"=201 OR "COD_PROD"=202 OR "COD_PROD"=205 OR "COD_PROD"=207 OR "COD_PROD"=229 OR "COD_PROD"=231 OR
              "COD_PROD"=232 OR "COD_PROD"=235 OR "COD_PROD"=250 OR "COD_PROD"=253 OR "COD_PROD"=256 OR "COD_PROD"=274 OR "COD_PROD"=278 OR
              "COD_PROD"=279 OR "COD_PROD"=284 OR "COD_PROD"=285 OR "COD_PROD"=293 OR "COD_PROD"=298 OR "COD_PROD"=299 OR "COD_PROD"=770 OR
              "COD_PROD"=801 OR "COD_PROD"=802 OR "COD_PROD"=804 OR "COD_PROD"=805 OR "COD_PROD"=806 OR "COD_PROD"=809 OR "COD_PROD"=810 OR
              "COD_PROD"=811 OR "COD_PROD"=813 OR "COD_PROD"=814 OR "COD_PROD"=816 OR "COD_PROD"=817 OR "COD_PROD"=818 OR "COD_PROD"=819 OR
              "COD_PROD"=820 OR "COD_PROD"=825 OR "COD_PROD"=826 OR "COD_PROD"=827 OR "COD_PROD"=830 OR "COD_PROD"=831 OR "COD_PROD"=832 OR
              "COD_PROD"=833 OR "COD_PROD"=835 OR "COD_PROD"=837 OR "COD_PROD"=838 OR "COD_PROD"=843 OR "COD_PROD"=844 OR "COD_PROD"=845 OR
              "COD_PROD"=846 OR "COD_PROD"=847 OR "COD_PROD"=848 OR "COD_PROD"=853 OR "COD_PROD"=862 OR "COD_PROD"=863 OR "COD_PROD"=864 OR
              "COD_PROD"=866 OR "COD_PROD"=867 OR "COD_PROD"=868 OR "COD_PROD"=871 OR "COD_PROD"=881 OR "COD_PROD"=893 OR "COD_PROD"=894 OR
              "COD_PROD"=895 OR "COD_PROD"=897) AND "FLG_MNT_STATUS"='A' AND "COD_ENTITY_VPD"=TO_NUMBER(NVL(SYS_CONTEXT('CLIENTCONTEXT','entity_
              code'),'0')))
  15 - filter("FLG_MNT_STATUS"='A' AND "COD_ENTITY_VPD"=TO_NUMBER(NVL(SYS_CONTEXT('CLIENTCONTEXT','entity_code'),'0')))

各テーブルに 100 を超える列が含まれていることを考慮すると、テーブル定義全体をアップロードする際に制限があります。ただし、where 句でアクセスされる列については、以下の詳細を参照してください。お役に立てれば。

Columns     Type    Nullable
cod_acct_no CHAR(16)    N
FLG_MNT_STATUS  CHAR(1)     N 
cod_23          VARCHAR2(360)   Y
cod_cc_brn  NUMBER(5)   N
cod_prod    NUMBER          N
4

2 に答える 2

1

1. テーブル全体のスキャンを恐れないでください。 テーブル内の行の大部分がアクセスされている場合は、ネストされたループ/インデックス スキャンよりもハッシュ結合/フル テーブル スキャンを使用する方が効率的です。

2. 統計を修正し、オブジェクトを再分析します。 テーブルを読むのに999時間?これはおそらくオプティマイザのバグです。DBA にselect * from sys.aux_stats$;ばかげた値を調べてもらいます。時間はあまり役に立ちませんが、予測値の 1 つが大幅にずれている場合は、それらすべてを確認する必要があります。おそらく、関連するすべてのテーブルの統計を再収集する必要があります。正当な理由がない限り、デフォルト設定を使用してください。たとえば、exec dbms_stats.gather_table_stats('your_schema_name','CH_ACCT_MAST');.

3. カーディナリティを見てください。Rows見積もりは球場にありますか ?それらが完璧になることはほとんどありませんが、1 桁または 2 桁以上ずれていると、問題が発生する可能性があります。最初の重要な違いを探して、それを修正してみてください。

4. コードの変更。 @Santhosh は、ANSI 結合を使用して書き直し、サブクエリを手動でネスト解除するという良い考えを持っていました。代わりに、他のサブクエリのネストを解除する必要があると思いますが。Oracle はサブクエリを自動的にネスト解除できますが、サブクエリに「集計関数が含まれている」場合はそうではありません。

5. VPD を無効 にする このクエリは変換されているようです。それが何をしているのか、そしてその理由を正確に理解していることを確認してください。この問題をデバッグしている間、VPD を一時的に無効にすることができます。

6. 並列性。これらのテーブルの一部は大きいため、並列ヒントを追加することをお勧めします。ただし、多くのリソースを使い果たしやすいので注意してください。これを行う前に、計画を正しく立てるようにしてください。

于 2013-04-06T05:50:40.367 に答える