关于where子句过滤谓词的Oracle性能问题

时间:2017-06-12 19:24:44

标签: oracle performance join indexing self

性能改进的新手,我正在努力解决以下问题。下表用于跟踪登记者的状态。每次状态更改时,都会为登记者插入新行。我试图获得给定登记者的最佳状态,以获得需要亚秒响应时间的Web界面。我已经更改了自联接以使用rank()和更新的索引,这确实有帮助,但是当我尝试添加where条件以查找给定的enrollment_process_status时,查询将花费一秒钟来响应。关于如何改进这个的任何建议?

 CREATE TABLE "TM"."ENRL_PROCESS_STATUS" 
   (    "ENRL_ENROLLEE_RECORD_SK" NUMBER(*,0) NOT NULL ENABLE, 
    "ENRL_PROCESS_STATUS_SK" NUMBER(*,0) NOT NULL ENABLE, 
    "ENROLLMENT_PROCESS_STATUS" NUMBER(*,0), 
    "BACKOUT_ID" NUMBER(*,0), 
    "CREATE_DTTM" TIMESTAMP (6), 
    "CREATE_LOGIN" VARCHAR2(50 BYTE), 
    "UPDATE_DTTM" TIMESTAMP (6), 
    "UPDATE_LOGIN" VARCHAR2(50 BYTE), 
    "PROCESS_STATUS_REASON_CD" NUMBER(*,0), 
     CONSTRAINT "ENRL_PROCESS_STATUS_PK" PRIMARY KEY ("ENRL_PROCESS_STATUS_SK")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"  ENABLE, 
     CONSTRAINT "ENRL_PROCESS_STATUS_FK1" FOREIGN KEY ("ENRL_ENROLLEE_RECORD_SK")
      REFERENCES "TM"."ENRL_ENROLLEE_RECORD" ("ENRL_ENROLLEE_RECORD_SK") ENABLE
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ;

  CREATE INDEX "TM"."TOM1" ON "TM"."ENRL_PROCESS_STATUS" ("ENRL_ENROLLEE_RECORD_SK", "CREATE_DTTM" DESC, "ENROLLMENT_PROCESS_STATUS", "PROCESS_STATUS_REASON_CD") 
  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ;

SQL以识别登记者的最新状态

SELECT enrl_enrollee_record_sk, enrollment_process_status, PROCESS_STATUS_REASON_CD 
  FROM
  (
    SELECT 
       enrl_enrollee_record_sk, enrollment_process_status, PROCESS_STATUS_REASON_CD, 
       rank() over (partition by enrl_enrollee_record_sk ORDER BY CREATE_DTTM DESC) as seqnum 
    FROM TM.enrl_process_status ps
  ) A  
WHERE seqnum = 1 
AND (ENROLLMENT_PROCESS_STATUS IN (3,4,5,8) OR (ENROLLMENT_PROCESS_STATUS = 10 AND PROCESS_STATUS_REASON_CD in (1,3)))

如果没有(AND)条件,查询将在0秒内运行,并带有以下解释计划。

Plan hash value: 2893856400

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  3420K|   169M|  7592   (1)| 00:01:47 |
|*  1 |  VIEW             |      |  3420K|   169M|  7592   (1)| 00:01:47 |
|*  2 |   WINDOW NOSORT   |      |  3420K|    71M|  7592   (1)| 00:01:47 |
|   3 |    INDEX FULL SCAN| TOM1 |  3420K|    71M|  7592   (1)| 00:01:47 |
--------------------------------------------------------------------------

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

   1 - filter("SEQNUM"=1)
   2 - filter(RANK() OVER ( PARTITION BY "ENRL_ENROLLEE_RECORD_SK" 
              ORDER BY SYS_OP_DESCEND("CREATE_DTTM"))<=1)

使用(AND)条件,查询运行时间超过1.2秒,并带有以下解释计划。关于如何提高绩效的任何想法?

Plan hash value: 2893856400

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  3420K|   169M|  7592   (1)| 00:01:47 |
|*  1 |  VIEW             |      |  3420K|   169M|  7592   (1)| 00:01:47 |
|*  2 |   WINDOW NOSORT   |      |  3420K|    71M|  7592   (1)| 00:01:47 |
|   3 |    INDEX FULL SCAN| TOM1 |  3420K|    71M|  7592   (1)| 00:01:47 |
--------------------------------------------------------------------------

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

   1 - filter("SEQNUM"=1 AND (("ENROLLMENT_PROCESS_STATUS"=3 OR 
              "ENROLLMENT_PROCESS_STATUS"=4 OR "ENROLLMENT_PROCESS_STATUS"=5 OR 
              "ENROLLMENT_PROCESS_STATUS"=8) OR "ENROLLMENT_PROCESS_STATUS"=10 AND 
              ("PROCESS_STATUS_REASON_CD"=1 OR "PROCESS_STATUS_REASON_CD"=3)))
   2 - filter(RANK() OVER ( PARTITION BY "ENRL_ENROLLEE_RECORD_SK" 
              ORDER BY SYS_OP_DESCEND("CREATE_DTTM"))<=1)

0 个答案:

没有答案