Indexes and Functions - 01
The user said me that the table has a index in
the date column that he used in his query SQL but is too slow.
That is true, this table (TB_EVENTS) has an index in date type column (EVNT_PK).
SQL> SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE FROM DBA_TAB_COLUMNS WHERE TABLE_NAME='TB_EVENTS' AND COLUMN_NAME='EVENT_DATE';
TABLE_NAME COLUMN_NAME DATA_TYPE
------------------------------
-------------------------------- ------------
TB_EVENTS EVENT_DATE DATE
SQL> SELECT COL.INDEX_NAME,
COL.COLUMN_NAME FROM SYS.DBA_IND_COLUMNS COL
WHERE OWNER='PSP' AND INDEX_NAME='EVNT_PK';
INDEX_NAME COLUMN_NAME
------------------------------
--------------------------------
EVNT_PK EVENT_DATE
Ok, He
use EVENT_DATE column in the WHERE but also use TO_CHAR function in order to
select all rows from yesterday. When we
use functions in column of an index, in certain cases we kill the index and
then the database does a full scan.
SQL> set autot trace exp stat
SQL>
select Event_Status
from PSP.TB_Events
WHERE TO_CHAR (Event_Date,'DDMMYYYY') = TO_CHAR(SYSDATE-1,'DDMMYYYY');
no rows selected
Elapsed: 00:04:18.75
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=RULE
1 0 TABLE ACCESS (FULL) OF 'TB_EVENTS' <--
Full scan, didn’t use the index
Statistics
----------------------------------------------------------
0
recursive calls
0
db block gets
651601 consistent gets
586208 physical reads <-- performance more physical reads.
356
redo size
308
bytes sent via SQL*Net to client
461
bytes received via SQL*Net from client
1
SQL*Net roundtrips to/from client
0
sorts (memory)
0
sorts (disk)
0
rows processed
We
rewrite the WHERE condition so that don’t use TO_CHAR function and continue to
obtain the same rows. And then... Database can use the index.
SQL> SELECT EVENT_STATUS
FROM PSP.TB_EVENTS
WHERE EVENT_DATE >= TRUNC (SYSDATE-1) AND EVENT_DATE < TRUNC (SYSDATE);
no rows selected
Elapsed: 00:02:08.14
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=RULE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TB_EVENTS'
2 1 INDEX (RANGE SCAN) OF 'EVNT_PK' (UNIQUE) <-- Used the index.
Statistics
----------------------------------------------------------
0
recursive calls
0
db block gets
732782 consistent gets
20769 physical reads <-- performance
less physical reads.
0
redo size
308
bytes sent via SQL*Net to client
461
bytes received via SQL*Net from client
1
SQL*Net roundtrips to/from client
0
sorts (memory)
0
sorts (disk)
0
rows processed
Comparison table
TO_CHAR (Event_Date,'DDMMYYYY') =
TO_CHAR(SYSDATE-1,'DDMMYYYY');
|
EVENT_DATE >= TRUNC (SYSDATE-1) AND
EVENT_DATE < TRUNC (SYSDATE)
|
|
Optimizer
|
TABLE ACCESS (FULL)
|
INDEX (RANGE SCAN)
|
Elapsed
|
00:04:18.75
|
00:02:08.14
|
physical reads
|
586208
|
20769
|
Comments
Post a Comment