0

次のクエリを実行しています。

SELECT * 
  FROM dblappc.credit_history 
 WHERE crd_effective_date > TO_DATE('20100801','YYYYMMDD') 
   AND o_crd_score > 650 
   AND crd_expiration_date IS NULL
  • 上記のテーブルにはインデックスがありません
  • crd_expiration_date主キーの一部です

クエリを高速化するにはどうすればよいですか?
ここで並列ヒントを使用して、少なくとも一度に 500 行を提供できますか?

以下はテーブル構造です。

CREATE TABLE DFQAPP13.CREDIT_HISTORY
(
  BAN                  NUMBER(9) CONSTRAINT CRHST_BAN_NN NOT NULL,
  CRD_SEQ_NO           NUMBER(9) CONSTRAINT CRDHST_CRD_SEQ_NO_NN NOT NULL,
  SYS_CREATION_DATE    DATE                     NOT NULL,
  SYS_UPDATE_DATE      DATE,
  OPERATOR_ID          NUMBER(9),
  APPLICATION_ID       CHAR(6 BYTE),
  DL_SERVICE_CODE      CHAR(5 BYTE),
  DL_UPDATE_STAMP      NUMBER(4),
  CRD_EFFECTIVE_DATE   DATE CONSTRAINT CRDHST_CRD_EFFECTIVE_DATE_NN NOT NULL,
  CRD_EXPIRATION_DATE  DATE,
  CRD_VET_TYPE         CHAR(4 BYTE),
  O_CRD_APPLIC_NUM     NUMBER(9),
  O_CRD_DECISION       CHAR(2 BYTE),
  O_CRD_SCORE          NUMBER(7),
  O_CRD_POLICY_RULE1   VARCHAR2(40 BYTE),
  O_CRD_POLICY_RULE2   VARCHAR2(40 BYTE),
  O_CRD_POLICY_RULE3   VARCHAR2(40 BYTE),
  O_CRD_POLICY_RULE4   VARCHAR2(40 BYTE),
  O_CRD_POLICY_RULE5   VARCHAR2(40 BYTE),
  O_CRD_POLICY_RULE6   VARCHAR2(40 BYTE),
  CRD_CLASS            CHAR(1 BYTE),
  CRD_CLASS_CHG_TYPE   CHAR(1 BYTE),
  CRD_CHG_RSN_TEXT     CHAR(100 BYTE),
  I_CRD_REQ_CTN_QTY    NUMBER(7),
  CRD_APR_CTN_QTY      NUMBER(7),
  I_CRD_BANK_BRANCH    VARCHAR2(100 BYTE),
  I_CRD_TACT_BANK_CD   CHAR(1 BYTE),
  I_CRD_BANK_DATE      DATE,
  I_ESAT_CUST_IND      CHAR(1 BYTE),
  O_DUNS_RET_CODE1     CHAR(4 BYTE),
  O_DUNS_RET_CODE2     CHAR(4 BYTE),
  O_DUNS_RET_NUM       VARCHAR2(18 BYTE),
  O_DUNS_NUM           NUMBER(9),
  O_DUNS_FIN_STRENGTH  CHAR(3 BYTE),
  O_DUNS_COMP_COND     CHAR(1 BYTE),
  O_DUNS_PAYM_SCORE    NUMBER(4),
  O_DUNS_CCJ1_EIRE     NUMBER(6),
  O_DUNS_CCJ2_EIRE     NUMBER(6),
  O_DUNS_CCJ3_EIRE     NUMBER(6),
  O_DUNS_CCJ4_EIRE     NUMBER(6),
  O_DUNS_CCJ5_EIRE     NUMBER(6),
  O_DUNS_CCJ1_UK       NUMBER(4),
  O_DUNS_CCJ2_UK       NUMBER(4),
  O_DUNS_CCJ3_UK       NUMBER(4),
  O_DUNS_CCJ4_UK       NUMBER(4),
  O_DUNS_CCJ5_UK       NUMBER(4),
  I_PHONE_TYPE         CHAR(3 BYTE),
  I_PAID_ENHANCE_NUM   NUMBER(1),
  I_CHURN_CUST_IND     CHAR(1 BYTE),
  I_EX_DIRECTORY_IND   CHAR(1 BYTE),
  I_ITEMISED_BIL_IND   CHAR(1 BYTE),
  CONV_RUN_NO          NUMBER(3)
)
4

3 に答える 3

2

テーブルのサイズ、既存のインデックス、実行計画、およびその他の詳細を知らなければ、アドバイスを与えることは困難です。

クエリは 2 つの範囲で検索しているため、インデックスだけを使用してすべての結果を取得するのは簡単ではありません。

ただし、最初に次の 2 つのオプションを試します。

  • orの単純索引crd_effective_dateおよび複合(crd_expiration_date, o_crd_score)

  • 単純索引オンo_crd_scoreおよび複合オン(crd_expiration_date, crd_effective_date)

以下を使用して、クエリの実行計画を確認できます (現在、インデックスなしで追加した後)。EXPLAIN PLAN

于 2011-07-11T09:55:56.450 に答える
0

1 つの特定の問題と、いくつかの一般的な改善点があります。

まず、null値はインデックス化されていないため、Oracle はおそらく、主キーの上にインデックスを構築するクエリに対して、フル インデックス スキャンまたはインデックス スキップ スキャン バリアントを選択します。本当に主キーに含める必要がある場合は、このクエリのフィールドのみcrd_expiration_dateに別のインデックスを作成します。o_crd_scorecrd_effective_date

create index X_CREDIT_HISTORY_DATE_SCORE 
  on CREDIT_HISTORY (o_crd_score, crd_effective_date)

その後、Oracle が新しいインデックスを使用しない場合は、クエリ テキストで強制的に使用します。

select /*+ index(hist_data X_CREDIT_HISTORY_DATE_SCORE) */ 
  * 
from 
  dblappc.credit_history hist_data
where 
  crd_effective_date>to_date('20100801','YYYYMMDD') 
  and 
  o_crd_score >650 
  and 
  crd_expiration_date is null

一般的な問題は一般的であり、以前の回答で言及されています。

  1. 本当に必要な特定のフィールドのみを選択します。
  2. 主キーにヌルを使用しないでください。
  3. 代理主キーが優先されます。

アップデート

おっと...以前の質問を読んでいるときに、「テーブルの上にインデックスがありません」というフレーズを見逃していました。

したがって、推奨事項は 1 つだけです。インデックスを作成するだけです。

于 2011-07-11T12:47:07.073 に答える
-2

あなたはそれをより速くすることができます

  • 結果の重量を減らしたい特定のアイテムを選択します。
  • WHERE 句ではo_crd_score >650、最初の場所、 crd_expiration_date is null2 番目の場所 crd_effective_date>to_date('20100801','YYYYMMDD')、最後にを使用します。

したがって、クエリは次のようになります。

SELECT a,b,d... 
FROM dblappc.credit_history
WHERE 
  o_crd_score >650 and 
  crd_expiration_date is null
  crd_effective_date>to_date('20100801','YYYYMMDD') and 

ここで行っているのは、フィルター処理されたレコードに日付チェックが適用されるように、レコードを最小限に短絡することです。

また、テーブルにINDEXを適用することで高速化できます。

于 2011-07-11T09:34:26.930 に答える