Hi there!
I've got some performance issues with an "delete ... where not exists" statement. The statement is executed via JDBC.
The statement looks like this:
CODE
DELETE FROM table_inputjob
WHERE inputfilestate =?
AND indexfilestate =?
AND NOT EXISTS(SELECT *
FROM table_job
WHERE table_job.inputid = table_inputjob.inputid)
Each table contains about 4500000 rows. The above statement took 115 seconds to delete 1098 rows from TABLE_INPUTJOB. A smaller run with 50 rows deleted took about 46 seconds. Another run was about to delete 2000000 rows, which I've canceled after several hours have passed. I need to delete this 2000000 rows in an acceptable amount of time.
Do you have any ideas to boost this statement?
Thanks in advance!
Here is the result from EXPLAIN PLAN (when the statement should delete 1036 rows):
CODE
Plan hash value: 3615700051
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 7872 | 615K| | 56776 (1)| 00:11:22 |
| 1 | DELETE | TABLE_INPUTJOB | | | | | |
|* 2 | HASH JOIN ANTI | | 7872 | 615K| 41M| 56776 (1)| 00:11:22 |
|* 3 | TABLE ACCESS FULL | TABLE_INPUTJOB | 787K| 32M| | 25398 (1)| 00:05:05 |
| 4 | INDEX FAST FULL SCAN| IDX_TJ_IIDJS | 4651K| 164M| | 18477 (1)| 00:03:42 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TABLE_JOB"."INPUTID"="TABLE_INPUTJOB"."INPUTID")
3 - filter("INDEXFILESTATE"=TO_NUMBER(:2) AND "INPUTFILESTATE"=TO_NUMBER(:1))
Table definition looks like this:
CODE
CREATE TABLE TABLE_INPUTJOB (
TASKNAMES VARCHAR2(4000),
INPUTID VARCHAR2(100) NOT NULL,
INPUTFILESTATE NUMBER(10),
EXECUTIONQUEUED DATE,
EXECUTIONSTART DATE,
EXECUTIONEND DATE,
PRIORITY NUMBER(10),
SERVERNAME VARCHAR2(100),
INDEXFILESTATE NUMBER(10),
OBSERVER VARCHAR2(50),
ALLJOBS NUMBER(10),
CONSTRAINT PK_TABLE_INPUTJOB PRIMARY KEY (INPUTID)
);
CREATE TABLE "TABLE_JOB" (
"JOBSTATE" NUMBER(10),
"DATETIME" DATE,
"USERNAME" VARCHAR2(50),
"DDONAME" VARCHAR2(1024) NOT NULL,
"TEXTSEARCH" VARCHAR2(4000),
"PROCESSED" NUMBER(10),
"ARCHIVED" NUMBER(1),
"ENABLED" NUMBER(1) NOT NULL,
"QUEUENAME" VARCHAR2(100),
"DOCTYPE" VARCHAR2(100),
"PAGECOUNT" NUMBER(10) NOT NULL,
"SHEETCOUNT" NUMBER(10) NOT NULL,
"COPY" NUMBER(10),
"ERRORDESCRIPTION" VARCHAR2(255),
"JOB_ID" VARCHAR2(36) UNIQUE NOT NULL,
"INPUTID" VARCHAR2(100) NOT NULL,
"JOBID" VARCHAR2(100) UNIQUE,
"LOCKED" NUMBER(10),
"LAST_OUTPUT" DATE,
"DOCTYPENR" NUMBER(10),
"EVENT_ID" VARCHAR2(36),
CONSTRAINT "PK_TABLE_JOB" PRIMARY KEY ("JOB_ID", "INPUTID")
);
ALTER TABLE "TABLE_JOB" ADD CONSTRAINT "FK_JOB_INPUTJOB" FOREIGN KEY (
"INPUTID"
)
REFERENCES "TABLE_INPUTJOB" (
"INPUTID"
) ON DELETE CASCADE;
CREATE INDEX IDX_TABLE_JOB
ON TABLE_JOB (INPUTID, JOB_ID) NOLOGGING;
CREATE INDEX IDX_TJ_IIDJS
ON TABLE_JOB (INPUTID, JOBSTATE) NOLOGGING;