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

在不知道表的大小、现有索引、执行计划和其他细节的情况下,很难给出任何建议。

由于查询在两个范围内进行搜索,因此仅使用索引来获取所有结果并不容易。

但我会先尝试这两个选项:

  • 简单的索引crd_effective_date和复合在(crd_expiration_date, o_crd_score)or

  • 简单索引o_crd_score和复合(crd_expiration_date, crd_effective_date)

您可以使用以下命令检查查询的执行计划(现在,没有索引并且在添加它们之后):EXPLAIN PLAN

于 2011-07-11T09:55:56.450 回答
0

有一个具体问题和一些一般性改进。

首先,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. 首选代理主键。

更新

哎呀......我之前阅读问题时错过了短语“Above table has no indexs”。

因此只有一个建议:只创建一个索引。

于 2011-07-11T12:47:07.073 回答
-2

您可以通过以下方式使其更快

  • 选择您要减少结果权重的特定项目。
  • 在 WHERE 子句中使用o_crd_score >650in the first place, crd_expiration_date is nullin second place and crd_effective_date>to_date('20100801','YYYYMMDD')in the last

所以查询会是这样的。

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 回答