Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.server -> Re: Composite index is not used for concatnated Date & Time fields?

Re: Composite index is not used for concatnated Date & Time fields?

From: Charles Hooper <hooperc2000_at_yahoo.com>
Date: 1 Nov 2006 04:50:28 -0800
Message-ID: <1162385428.544084.278630@m7g2000cwm.googlegroups.com>


Shailesh wrote:
> Hello,
>
> We are using Oracle Versions 8.1.7.4, 10.2.0.2 on Windoes 2000/2003.
>
> We have two columns in a table (MovementDate, Movementtime) with data
> type DATE, one stores DATE and another stores Time. (Database is
> migrated from Sqlbase to Oracle that is why like this else in Oracle
> date time can be stored in same field and now we have inherited some of
> these practices) Composite index exist on these columns. Problem occurs
> when in condition we extract date part from first column and time part
> from another column using concatenation. Also sometimes time part is
> null, to take care of this issue we use NVL(). All this adds to "INDEX
> NOT USED" full table scan.
>
> How can we avoid this? Is there any way, please let me know.
>
> Sample script given below.
>
> CREATE TABLE TblMovement
> (
> FID NUMBER(38),
> columns.....,
> MovementDate DATE,
> Movementtime DATE,
> STORE VARCHAR2(30)
> );
>
> CREATE INDEX X1TblMovement ON TblMovement
> (FID);
>
> CREATE INDEX X2TblMovement ON TblMovement
> (MovementDate, Movementtime);
>
> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
>
> SELECT *
> FROM TblMovement
> WHERE TO_DATE (TO_CHAR (MovementDate, 'yyyy-MM-dd') || TO_CHAR
> (Movementtime, 'hh24:mi:ss'), 'YYYY-MM-DD HH24:MI:SS') <= TO_DATE
> ('2006-08-31 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
> AND Store IS NULL
> ORDER BY MovementDate DESC, TO_DATE (TO_CHAR (Movementtime,
> 'HH24:MI:SS'), 'HH24:MI:SS') DESC;
>
>
> Thanks & Regards,
>
> Shailesh

You may be able to use something like the following, which should be able to make use of the index if the MOVEMENTDATE is the leading column in the composite index - skip scans in 10g could still permit the use of the index if MOVEMENTDATE is not the leading column: SELECT
  *
FROM
  TBLMOVEMENT
WHERE
  MOVEMENTDATE < TO_DATE ('2006-08-31', 'YYYY-MM-DD')   AND STORE IS NULL
UNION ALL
SELECT
  *
FROM
  TBLMOVEMENT
WHERE
  MOVEMENTDATE = TO_DATE ('2006-08-31', 'YYYY-MM-DD')   AND (MOVEMENTTIME IS NULL
    OR TO_CHAR(MOVEMENTTIME, 'HH24:MI:SS') <= '00:00:00')   AND STORE IS NULL
ORDER BY
  MOVEMENTDATE DESC,
  MOVEMENTTIME DESC; The above makes the assumption that if you specify that a date must be <= to '2006-08-31', 'YYYY-MM-DD' at midnight, the acceptable date is either less than '2006-08-31', 'YYYY-MM-DD' or is equal to '2006-08-31', 'YYYY-MM-DD' with the time column either null or at '00:00:00'. I used TO_CHAR(MOVEMENTTIME) to strip out the date component of this column. If the date portion of this column shows '1899-12-30', 'YYYY-MM-DD', you may be able to further improve performance by changing this portion of the SQL statement to show:   AND (MOVEMENTTIME IS NULL
    OR MOVEMENTTIME <= TO_DATE('1899-12-30 00:00:00','YYYY-MM-DD HH24:MI:SS'))

You may find that it is sufficient to completely remove everything from the UNION ALL to the end of the SQL statement.

Charles Hooper
PC Support Specialist
K&M Machine-Fabricating, Inc. Received on Wed Nov 01 2006 - 06:50:28 CST

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US