Re: Index not used to avoid sort with calculated column
Date: Wed, 26 Jun 2019 12:21:06 -0400
Message-ID: <CAMHX9JJ4pFFhWArCA3h6R-r_mDPqPBwOCYg42QBQdxximQCvGg_at_mail.gmail.com>
The function-based-index column -> virtual column transformation causes
trouble here. You can set the virtual column replacement feature to false
and try again:
SQL> ALTER SESSION SET "*_replace_virtual_columns*"=false;
Session altered.
SQL> select * from emp where lower(job)=lower('CLERK') order by hiredate
fetch first 2 rows only;
SQL> _at_x
Predicate Information (identified by operation id):
This MOS note describes the issue:
Also, should be aware of bugs & issues in some versions:
EMPNO ENAME JOB MGR HIREDATE SAL
COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ----------
---------- ----------
7369 SMITH CLERK 7902 1980-12-17 00:00:00 800
20
7900 JAMES CLERK 7698 1981-12-03 00:00:00 950
30
Display execution plan for last statement for this session from library
cache...
| Id | Operation | Name | E-Rows |E-Bytes| Cost
(%CPU)|
| 0 | SELECT STATEMENT | | | |
3 (100)|
|* 1 | VIEW | | 2 | 218 |
3 (34)|
|* 2 | WINDOW *NOSORT* STOPKEY | | 1 | 38 |
3 (34)|
| 3 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 38 |
2 (0)|
|* 4 | INDEX RANGE SCAN | E_LOW_SORT1 | 1 | |
1 (0)|
1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=2)
2 - filter(ROW_NUMBER() OVER ( ORDER BY "EMP"."HIREDATE")<=2)
4 - access("EMP"."SYS_NC00009$"='clerk')
--
Tanel Poder
https://blog.tanelpoder.com/seminar
On Wed, Jun 26, 2019 at 9:20 AM l.flatz_at_bluewin.ch <l.flatz_at_bluewin.ch>
wrote:
> Hi,
>
> My testcase below is based on the Scott schema.
>
> create index e_sort1 on emp (job, hiredate);
> create index e_low_sort1 on emp (lower(job), hiredate);
>
> Index e_sort1 can be used to avoid sorting.
>
> select * from emp where job='CLERK' order by hiredate fetch first 2 rows
> only;
>
>
>
> -----------------------------------------------------------------------------------------
> | 0 | SELECT STATEMENT | | | | 2
> (100)| |
> |* 1 | VIEW | | 2 | 218 | 2
> (0)| 00:00:01 |
> |* 2 | WINDOW NOSORT STOPKEY | | 4 | 348 | 2
> (0)| 00:00:01 |
> | 3 | TABLE ACCESS BY INDEX ROWID| EMP | 4 | 348 | 2
> (0)| 00:00:01 |
> |* 4 | INDEX RANGE SCAN | E_SORT1 | 1 | | 1
> (0)| 00:00:01 |
>
> -----------------------------------------------------------------------------------------
>
> Predicate Information (identified by operation id):
> ---------------------------------------------------
>
> 1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=2)
> 2 - filter(ROW_NUMBER() OVER ( ORDER BY "EMP"."HIREDATE")<=2)
> 4 - access("JOB"='CLERK')
>
> The function based index can not be used to avoid sorting.
> select * from emp where lower(job)=lower('CLERK') order by hiredate fetch
> first 2 rows only;
>
> -----------------------------------------------------------------------------------------------------
>
> | Id | Operation | Name | Rows |
> Bytes | Cost (%CPU)| Time |
> -----------------------------------------------------------------------------------------------------
>
> | 0 | SELECT STATEMENT | |
> | | 2 (100)| |
> |* 1 | VIEW | | 2 |
> 218 | 2 (0)| 00:00:01 |
> |* 2 | WINDOW SORT PUSHED RANK | | 4 |
> 372 | 2 (0)| 00:00:01 |
> | 3 | TABLE ACCESS BY INDEX ROWID BATCHED| EMP | 4 |
> 372 | 2 (0)| 00:00:01 |
> |* 4 | INDEX RANGE SCAN | E_LOW_SORT1 | 1
> | | 1 (0)| 00:00:01 |
> -----------------------------------------------------------------------------------------------------
>
>
> Predicate Information (identified by operation id):
> ---------------------------------------------------
>
> 1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=2)
> 2 - filter(ROW_NUMBER() OVER ( ORDER BY "EMP"."HIREDATE")<=2)
> 4 - access("EMP"."SYS_NC00009$"='clerk')
>
> What do I miss out here ?
>
> Thanks & Regards
>
> Lothar
>
>
--
http://www.freelists.org/webpage/oracle-l
Received on Wed Jun 26 2019 - 18:21:06 CEST