Tom :
Thanks for the help.
I now have a much better understanding of what caused the high LIO.
This is a great forum!
===
BACKGROUND : TABLES MY TESTING WAS PERFORMED ON
CREATE table DBA_TEST.TEST
(testnumber1 number(10,0) ,
testnumber2 number(10,0) ,
testdate date
)
tablespace TOOLS
pctfree 10
pctused 40 ;
alter table DBA_TEST.TEST
add constraint TEST_PK
primary key (testnumber1)
using index tablespace TOOLS ;
create index DBA_TEST.TEST_IX01
on DBA_TEST.TEST ( testnumber2 )
tablespace TOOLS ;
insert into DBA_TEST.TEST ( TESTNUMBER1, TESTNUMBER2, TESTDATE ) values (1, 1, SYSDATE ) ;
insert into DBA_TEST.TEST ( TESTNUMBER1, TESTNUMBER2, TESTDATE ) values (2, 2, SYSDATE ) ;
insert into DBA_TEST.TEST ( TESTNUMBER1, TESTNUMBER2, TESTDATE ) values (3, 3, SYSDATE ) ;
insert into DBA_TEST.TEST ( TESTNUMBER1, TESTNUMBER2, TESTDATE ) values (4, 4, SYSDATE ) ;
insert into DBA_TEST.TEST ( TESTNUMBER1, TESTNUMBER2, TESTDATE ) values (5, 5, SYSDATE ) ;
insert into DBA_TEST.TEST ( TESTNUMBER1, TESTNUMBER2, TESTDATE ) values (6, 6, SYSDATE ) ;
insert into DBA_TEST.TEST ( TESTNUMBER1, TESTNUMBER2, TESTDATE ) values (7, 7, SYSDATE ) ;
insert into DBA_TEST.TEST ( TESTNUMBER1, TESTNUMBER2, TESTDATE ) values (8, 8, SYSDATE ) ;
insert into DBA_TEST.TEST ( TESTNUMBER1, TESTNUMBER2, TESTDATE ) values (9, 9, SYSDATE ) ;
commit ;
CREATE table DBA_TEST.TEST_DRIVING_TABLE
(PKNUMBER number(10,0) ,
DRIVENUMBER1 number(10,0) ,
testdate date
)
tablespace TOOLS
pctfree 10
pctused 40 ;
alter table DBA_TEST.TEST_DRIVING_TABLE
add constraint TEST_DRIVING_TABLE_PK
primary key (PKNUMBER)
using index tablespace TOOLS ;
insert into DBA_TEST.TEST_DRIVING_TABLE ( PKNUMBER, DRIVENUMBER1, TESTDATE ) values (1, 1, SYSDATE ) ;
insert into DBA_TEST.TEST_DRIVING_TABLE ( PKNUMBER, DRIVENUMBER1, TESTDATE ) values (2, 2, SYSDATE ) ;
insert into DBA_TEST.TEST_DRIVING_TABLE ( PKNUMBER, DRIVENUMBER1, TESTDATE ) values (3, 3, SYSDATE ) ;
insert into DBA_TEST.TEST_DRIVING_TABLE ( PKNUMBER, DRIVENUMBER1, TESTDATE ) values (4, 4, SYSDATE ) ;
insert into DBA_TEST.TEST_DRIVING_TABLE ( PKNUMBER, DRIVENUMBER1, TESTDATE ) values (5, 5, SYSDATE ) ;
insert into DBA_TEST.TEST_DRIVING_TABLE ( PKNUMBER, DRIVENUMBER1, TESTDATE ) values (6, 6, SYSDATE ) ;
insert into DBA_TEST.TEST_DRIVING_TABLE ( PKNUMBER, DRIVENUMBER1, TESTDATE ) values (7, 7, SYSDATE ) ;
insert into DBA_TEST.TEST_DRIVING_TABLE ( PKNUMBER, DRIVENUMBER1, TESTDATE ) values (8, 8, SYSDATE ) ;
insert into DBA_TEST.TEST_DRIVING_TABLE ( PKNUMBER, DRIVENUMBER1, TESTDATE ) values (9, 9, SYSDATE ) ;
commit ;
===================================================================
** Q1 : 'row by row' is 'slow by slow'
I wanted to see this in an example - so I ran a test on my small DBA_TEST table.
The CURRENT mode gets were the same : 51 (set delete) vs 51 (4+47 on the driver delete).
The CONSISTENT GETS (QUERY) was dramatically higher : 19 (set delete) vs 27 (9+18 on the driver delete).
ALTER SESSION SET SQL_TRACE=TRUE
DECLARE
BEGIN
delete from DBA_TEST.TEST
where TESTNUMBER2 in ( SELECT DRIVENUMBER1 FROM DBA_TEST.TEST_DRIVING_TABLE ) ;
END;
/
ALTER SESSION SET SQL_TRACE=FALSE
DECLARE
BEGIN
delete from DBA_TEST.TEST
where TESTNUMBER2 in ( SELECT DRIVENUMBER1 FROM DBA_TEST.TEST_DRIVING_TABLE ) ;
END;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.01 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.01 0.01 0 0 0 1
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: SYS
********************************************************************************
DELETE FROM DBA_TEST.TEST
WHERE
TESTNUMBER2 IN (SELECT DRIVENUMBER1 FROM DBA_TEST.TEST_DRIVING_TABLE )
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 19 51 9
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 19 51 9
---
ALTER SESSION SET SQL_TRACE=TRUE ;
DECLARE
p_drivernumber NUMBER(10);
CURSOR RowsToDelete_Cur IS
SELECT DRIVENUMBER1 FROM DBA_TEST.TEST_DRIVING_TABLE ;
BEGIN
OPEN RowsToDelete_Cur;
LOOP
FETCH RowsToDelete_Cur INTO p_drivernumber ;
IF RowsToDelete_Cur%NOTFOUND
THEN
EXIT;
ELSE
delete from DBA_TEST.TEST where TESTNUMBER2 = p_drivernumber ;
END IF;
END LOOP;
END;
/
ALTER SESSION SET SQL_TRACE=FALSE ;
DECLARE
p_drivernumber NUMBER(10);
CURSOR RowsToDelete_Cur IS
SELECT DRIVENUMBER1 FROM DBA_TEST.TEST_DRIVING_TABLE ;
BEGIN
OPEN RowsToDelete_Cur;
LOOP
FETCH RowsToDelete_Cur INTO p_drivernumber ;
IF RowsToDelete_Cur%NOTFOUND
THEN
EXIT;
ELSE
delete from DBA_TEST.TEST where TESTNUMBER2 = p_drivernumber ;
END IF;
END LOOP;
END;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.01 0.01 0 0 0 0
Execute 1 0.01 0.01 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.02 0.02 0 0 0 1
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: SYS
********************************************************************************
SELECT DRIVENUMBER1
FROM
DBA_TEST.TEST_DRIVING_TABLE
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 10 0.00 0.00 0 9 4 9
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 12 0.00 0.00 0 9 4 9
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: SYS (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
9 TABLE ACCESS FULL TEST_DRIVING_TABLE
Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT GOAL: CHOOSE
9 TABLE ACCESS (FULL) OF 'TEST_DRIVING_TABLE'
********************************************************************************
DELETE FROM DBA_TEST.TEST
WHERE
TESTNUMBER2 = :b1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 9 0.02 0.02 0 18 47 9
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 10 0.02 0.02 0 18 47 9
===================================================================
** Q2 PROBLEM RESOLVED : WHY AM I SEEING 455,120 EXECUTIONS OF THE DELETE STATEMENT WHEN I COUNT ONLY 286,864 RECS ?
Your response (you must have had *more* of them) got me to thinking about what happened that day.
The original procedure selected *more* records (493,000) :
WHERE rate_stat = 'C'
AND TRUNC(usg_dttm) < TRUNC(ADD_MONTHS(SYSDATE, -5));
Because it ran so long we killed it and changed the procedure to select less records but never got around to kicking it off again.
WHERE rate_stat = 'C'
AND TRUNC(usg_dttm) < TRUNC(ADD_MONTHS(SYSDATE, -6));
So the next day when I noticed the high LIO in my STATSPACK report - I had forgotten that we changed the procedure - which led to my confusion.
My appologies on this.
===================================================================
** Q3 PROBLEM RESOLVED : WHY AM I GETTING ZERO CONSISTENT GETS
I did some more playing around on this and uncovered the problem : I did not have sufficient PRIVS when I ran AUTOTRACE.
When I was signed on as '/ SYSDBA' and ran AUTOTRACE I got the 0 consistent gets (see below).
Then thought I would generate a TRACE file - when I tried to 'ALTER SESSION SET SQL_TRACE=TRUE' I got a 'ORA-01031: insufficient privileges'.
I signed on as SYS and reran AUTOTRACE and low and behold I got a reading on consistent gets.
SQL> set autotrace on
SQL> DELETE FROM DBA_TEST.TEST WHERE TESTNUMBER2 = 2 ;
1 row deleted.
Execution Plan
----------------------------------------------------------
0 DELETE STATEMENT Optimizer=CHOOSE
1 0 DELETE OF 'TEST'
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'
3 2 INDEX (RANGE SCAN) OF 'TEST_IX01' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
0 bytes sent via SQL*Net to client
0 bytes received via SQL*Net from client
0 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> set autotrace off
SQL> ALTER SESSION SET SQL_TRACE=TRUE ;
ERROR:
ORA-01031: insufficient privileges
SQL> connect sys@blcopy
Enter password:
Connected.
SQL> set autotrace on
SQL> DELETE FROM DBA_TEST.TEST WHERE TESTNUMBER2 = 5 ;
1 row deleted.
Execution Plan
----------------------------------------------------------
0 DELETE STATEMENT Optimizer=CHOOSE
1 0 DELETE OF 'TEST'
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'
3 2 INDEX (RANGE SCAN) OF 'TEST_IX01' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
7 db block gets
2 consistent gets
0 physical reads
1076 redo size
644 bytes sent via SQL*Net to client
476 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
1 rows processed