Home » RDBMS Server » Performance Tuning » Analytical Functions and Backward Index scans
Analytical Functions and Backward Index scans [message #307386] |
Tue, 18 March 2008 13:43 |
verpies
Messages: 28 Registered: March 2008 Location: Seattle
|
Junior Member |
|
|
I am having a problem that the analytical functions do not use the Oracle BTree indexes backward (although I thought that indexes are bidirectional in Oracle 10g, and long before that).
For example, in the queries below, the index is used by the analytical function only in cases A and D.
In other cases index is not used, as evidenced by the undesirable "WINDOW SORT" in the query plan.
Also, it is necessary to use the SYS_OP_DESCEND() function to coerce the RDBMS to use a descending index even in the forward direction for an analytical fn.
Summary:
-------------------
A) CAN use an ascending index FORWARD. (good Window NoSort in query plan)
B) CANNOT use an ascending index BACKWARD (bad Window Sort appears in query plan).
D) CAN use a descending index FORWARD only after coercion with SYS_OP_DESCEND function. (good Window NoSort in query plan)
E) CANNOT use a descending index BACKWARD. (bad Window Sort appears in query plan).
Do any one of you have any info what is going on inside RDBMS that would cause this ?
Regards,
George Robinson
DROP INDEX IDX_USE_ME;
CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME ASC, ID ASC);
/* CASE A: THE ANALYTIC FN USES THE INDEX FORWARD*/
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME ASC, ID ASC
)
WHERE rownum<=22
/* CASE B: THE ANALYTIC FN DOES NOT USE THE INDEX BACKWARD*/
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_DESC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME DESC, ID DESC
)
WHERE rownum<=22
/* NOW LETS CREATE A DESCENDING INDEX FOR CASES C,D,E */
DROP INDEX IDX_USE_ME;
CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME DESC, ID DESC);
/* CASE C: THE ANALYTIC FN DOES NOT USE THE INDEX FORWARD*/
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME DESC, ID DESC
) a
WHERE rownum<=22
/* CASE D: THE ANALYTIC FN USES THE INDEX FORWARD AFTER COERCION WITH SYS_OP_DESCEND */
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SYS_OP_DESCEND(SNAME) ORDER BY SNAME DESC, ID DESC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME DESC, ID DESC
) a
WHERE rownum<=22
/* CASE E: THE ANALYTIC FN DOES NOT USE THE INDEX BACKWARD */
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_DESC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME ASC, ID ASC
) a
WHERE rownum<=22
|
|
|
|
Re: Analytical Functions and Backward Index scans [message #307389 is a reply to message #307386] |
Tue, 18 March 2008 14:04 |
verpies
Messages: 28 Registered: March 2008 Location: Seattle
|
Junior Member |
|
|
The version I tried this on was 9i and 10g (eg.: 10.2.0.3.0), but any version supporting the analytics will do.
Are you sure a full test case is necessary for such trivial queries ?
Q1: Can you get "WINDOW NOSORT" in the query plan of Case A ?
Q2: Can you get "WINDOW NOSORT" in the query plan of Case B ?
If you do not observe a difference between these two queries and your answer for Q1 & Q2 is the same, I will gladly post a full test case.
Also, I do not have any choice about NOT USING the SYS_OP_DESCEND function in Case D.
Without it, the analytic Fn does not use any descending indices AT ALL !!! (neither forward nor backward...)
Thanks for the feedback,
George Robinson
[Updated on: Tue, 18 March 2008 14:22] Report message to a moderator
|
|
|
|
Re: Analytical Functions and Backward Index scans [message #307392 is a reply to message #307386] |
Tue, 18 March 2008 14:43 |
verpies
Messages: 28 Registered: March 2008 Location: Seattle
|
Junior Member |
|
|
Hi,
It's not that I do not want to make the effort.
Just thought it is too trivial to list it all here.
Anyway here it goes:
SQL> DROP INDEX IDX_USE_ME;
Index dropped.
SQL> CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME ASC, ID ASC);
Index created.
SQL> exec DBMS_STATS.GATHER_INDEX_STATS (ownname => 'ORAUSER', indname => 'IDX_USE_ME');
PL/SQL procedure successfully completed.
Commit complete.
SQL>
SQL> /* CASE A: THE ANALYTIC FN USES THE INDEX FORWARD*/
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 )
10 WHERE rownum<=9;
I SNAME
---------- ---------------------------------------------------------------------
1 /1000e8d1_LinkedHashMapValueIt
2 /1000e8d1_LinkedHashMapValueIt
1 /1005bd30_LnkdConstant
2 /1005bd30_LnkdConstant
1 /10076b23_OraCustomDatumClosur
2 /10076b23_OraCustomDatumClosur
1 /100c1606_StandardMidiFileRead
2 /100c1606_StandardMidiFileRead
1 /1013c29d_PlanarImageServerPro
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3940838639
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | 671 (2)| 00:00:09
|* 1 | COUNT STOPKEY | | | | |
| 2 | VIEW | | 49849 | 2677K| 671 (2)| 00:00:09
| 3 | WINDOW NOSORT | | 49849 | 1363K| 671 (2)| 00:00:09
| 4 | INDEX FULL SCAN| IDX_USE_ME | 49849 | 1363K| 274 (1)| 00:00:04
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
701 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
9 rows processed
SQL>
SQL>
SQL> /* CASE B: THE ANALYTIC FN DOES NOT USE THE INDEX BACKWARD*/
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_DESC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME DESC, ID DESC
9 )
10 WHERE rownum<=9;
I SNAME
---------- ---------------------------------------------------------------------
1 yCbCrSubSamplingType221_T
1 yCbCrPositioningType220_T
1 yCbCrCoefficientsType210_T
1 xmpMetadataType100_T
1 xml-extension-type31_T
1 xdbconfig60_T
1 xdb-log9_TAB$xd
1 xdb-log9_TAB
1 xdb-log7_T
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 733892884
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CP
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | | 1069 (
|* 1 | COUNT STOPKEY | | | | |
| 2 | VIEW | | 49849 | 2677K| | 1069 (
|* 3 | SORT ORDER BY STOPKEY| | 49849 | 1363K| 3544K| 1069 (
| 4 | WINDOW SORT | | 49849 | 1363K| 3544K| 1069 (
| 5 | INDEX FULL SCAN | IDX_USE_ME | 49849 | 1363K| | 274 (
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
3 - filter(ROWNUM<=9)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
272 consistent gets
0 physical reads
0 redo size
707 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
9 rows processed
SQL>
SQL>
SQL>
SQL> /* NOW LETS CREATE A DESCENDING INDEX FOR CASES C,D,E */
SQL> DROP INDEX IDX_USE_ME;
Index dropped.
SQL> CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME DESC, ID DESC);
Index created.
SQL> exec DBMS_STATS.GATHER_INDEX_STATS (ownname => 'ORAUSER', indname => 'IDX_USE_ME');
PL/SQL procedure successfully completed.
Commit complete.
SQL>
SQL> /* CASE C: THE ANALYTIC FN DOES NOT USE THE INDEX FORWARD*/
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME DESC, ID DESC
9 ) a
10 WHERE rownum<=9;
I SNAME
---------- ---------------------------------------------------------------------
1 yCbCrSubSamplingType221_T
1 yCbCrPositioningType220_T
1 yCbCrCoefficientsType210_T
1 xmpMetadataType100_T
1 xml-extension-type31_T
1 xdbconfig60_T
1 xdb-log9_TAB$xd
1 xdb-log9_TAB
1 xdb-log7_T
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 733892884
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CP
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | | 1083 (
|* 1 | COUNT STOPKEY | | | | |
| 2 | VIEW | | 49849 | 2677K| | 1083 (
|* 3 | SORT ORDER BY STOPKEY| | 49849 | 1363K| 3544K| 1083 (
| 4 | WINDOW SORT | | 49849 | 1363K| 3544K| 1083 (
| 5 | INDEX FULL SCAN | IDX_USE_ME | 49849 | 1363K| | 288 (
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
3 - filter(ROWNUM<=9)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
286 consistent gets
0 physical reads
0 redo size
707 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
9 rows processed
SQL>
SQL>
SQL> /* CASE D: THE ANALYTIC FN USES THE INDEX FORWARD AFTER COERCION WITH SYS_OP_DESCEND */
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SYS_OP_DESCEND(SNAME) ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME DESC, ID DESC
9 ) a
10 WHERE rownum<=9;
I SNAME
---------- ---------------------------------------------------------------------
1 yCbCrSubSamplingType221_T
1 yCbCrPositioningType220_T
1 yCbCrCoefficientsType210_T
1 xmpMetadataType100_T
1 xml-extension-type31_T
1 xdbconfig60_T
1 xdb-log9_TAB$xd
1 xdb-log9_TAB
1 xdb-log7_T
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3940838639
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | 1083 (2)| 00:00:13
|* 1 | COUNT STOPKEY | | | | |
| 2 | VIEW | | 49849 | 2677K| 1083 (2)| 00:00:13
| 3 | WINDOW NOSORT | | 49849 | 1363K| 1083 (2)| 00:00:13
| 4 | INDEX FULL SCAN| IDX_USE_ME | 49849 | 1363K| 288 (1)| 00:00:04
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
707 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
9 rows processed
SQL>
SQL>
SQL> /* CASE E: THE ANALYTIC FN DOES NOT USE THE INDEX BACKWARD */
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_DESC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 ) a
10 WHERE rownum<=9;
I SNAME
---------- ---------------------------------------------------------------------
1 /1000e8d1_LinkedHashMapValueIt
2 /1000e8d1_LinkedHashMapValueIt
1 /1005bd30_LnkdConstant
2 /1005bd30_LnkdConstant
1 /10076b23_OraCustomDatumClosur
2 /10076b23_OraCustomDatumClosur
1 /100c1606_StandardMidiFileRead
2 /100c1606_StandardMidiFileRead
1 /1013c29d_PlanarImageServerPro
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 733892884
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CP
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | | 685 (
|* 1 | COUNT STOPKEY | | | | |
| 2 | VIEW | | 49849 | 2677K| | 685 (
|* 3 | SORT ORDER BY STOPKEY| | 49849 | 1363K| 3544K| 685 (
| 4 | WINDOW SORT | | 49849 | 1363K| 3544K| 685 (
| 5 | INDEX FULL SCAN | IDX_USE_ME | 49849 | 1363K| | 288 (
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
3 - filter(ROWNUM<=9)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
286 consistent gets
0 physical reads
0 redo size
701 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
9 rows processed
SQL>
|
|
|
|
|
Re: Analytical Functions and Backward Index scans [message #307396 is a reply to message #307386] |
Tue, 18 March 2008 15:09 |
verpies
Messages: 28 Registered: March 2008 Location: Seattle
|
Junior Member |
|
|
Dear Barbara
Here is a script for creating the table and generating data for it from ALL_OBJECTS.
Analyzing the table and indices makes a difference for non-analytic functions (e.g.: the regular ORDER BY clause after the FROM clause).
However it makes no difference for the analytic function
Please note that there are 2 problems.
1) Analytic Fn not using the index backwards in any case (neither ascending nor descending index)
2) Analytic Fn not using the descending index (neither forward nor backward), without coercion with SYS_OP_DESCEND (which helps only in forward direction).
See for yourself...
DROP TABLE ORAUSER.CUSTOMER;
CREATE TABLE ORAUSER.CUSTOMER
(
ID NUMBER(10),
SNAME VARCHAR2(80 BYTE) NOT NULL,
FNAME VARCHAR2(50 BYTE),
DOB DATE
);
INSERT INTO CUSTOMER (ID, FNAME, SNAME, DOB)
SELECT rownum, CHR(mod(rownum,26)+64) || substr(to_char(TIMESTAMP),4,14), to_char(OBJECT_NAME), LAST_DDL_TIME
FROM ALL_OBJECTS;
exec DBMS_STATS.GATHER_TABLE_STATS (ownname => 'ORAUSER', tabname => 'CUSTOMER');
[Updated on: Tue, 18 March 2008 15:14] Report message to a moderator
|
|
|
Re: Analytical Functions and Backward Index scans [message #307397 is a reply to message #307396] |
Tue, 18 March 2008 15:43 |
|
Barbara Boehmer
Messages: 9100 Registered: November 2002 Location: California, USA
|
Senior Member |
|
|
I am getting different results. The only one that does not appear to use the index is E. I don't know if this is due to differences in versions (I am using 11g) or data (in all_objects) or if we did something different. Did you remember to run dbms_stats.gather_table_stats again after you dropped and recreated the index? I have provided below first my results, followed by the script that produced it, so that you can copy and paste and run it to make sure that we are running the same thing and see if you still get the same results.
-- results:
SCOTT@orcl_11g> DROP TABLE CUSTOMER
2 /
Table dropped.
SCOTT@orcl_11g> CREATE TABLE CUSTOMER
2 (
3 ID NUMBER(10),
4 SNAME VARCHAR2(80 BYTE) NOT NULL,
5 FNAME VARCHAR2(50 BYTE),
6 DOB DATE
7 )
8 /
Table created.
SCOTT@orcl_11g> INSERT INTO CUSTOMER (ID, FNAME, SNAME, DOB)
2 SELECT rownum, CHR(mod(rownum,26)+64) || substr(to_char(TIMESTAMP),4,14), to_char(OBJECT_NAME), LAST_DDL_TIME
3 FROM ALL_OBJECTS
4 /
68625 rows created.
SCOTT@orcl_11g> CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME ASC, ID ASC)
2 /
Index created.
SCOTT@orcl_11g> exec DBMS_STATS.GATHER_TABLE_STATS (USER, 'CUSTOMER')
PL/SQL procedure successfully completed.
SCOTT@orcl_11g> /* CASE A: THE ANALYTIC FN USES THE INDEX FORWARD*/
SCOTT@orcl_11g> SET AUTOTRACE ON EXPLAIN
SCOTT@orcl_11g> SELECT
2 SNAME, I
3 FROM (
4 SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 )
10 WHERE rownum<=22
11 /
SNAME I
-------------------------------------------------------------------------------- ----------
/1000323d_DelegateInvocationHa 1
/1000323d_DelegateInvocationHa 2
/1000e8d1_LinkedHashMapValueIt 1
/1000e8d1_LinkedHashMapValueIt 2
/1005bd30_LnkdConstant 1
/1005bd30_LnkdConstant 2
/10076b23_OraCustomDatumClosur 1
/10076b23_OraCustomDatumClosur 2
/100c1606_StandardMidiFileRead 1
/100c1606_StandardMidiFileRead 2
/100cb3d7_DicomLocatorPathDico 1
/100cb3d7_DicomLocatorPathDico 2
/10128284_OpenMBeanAttributeIn 1
/10128284_OpenMBeanAttributeIn 2
/1013c29d_PlanarImageServerPro 1
/1013c29d_PlanarImageServerPro 2
/101419a4_NormalDataCollector 1
/101419a4_NormalDataCollector 2
/1020ed5e_Param 1
/1020ed5e_Param 2
/1023e902_OraCharsetUTFE 1
/1023e902_OraCharsetUTFE 2
22 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3940838639
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 1210 | 379 (1)| 00:00:05 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 68625 | 3685K| 379 (1)| 00:00:05 |
| 3 | WINDOW NOSORT | | 68625 | 2010K| 379 (1)| 00:00:05 |
| 4 | INDEX FULL SCAN| IDX_USE_ME | 68625 | 2010K| 379 (1)| 00:00:05 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=22)
SCOTT@orcl_11g> /* CASE B: THE ANALYTIC FN DOES NOT USE THE INDEX BACKWARD*/
SCOTT@orcl_11g> -- ON MY SYSTEM, IT DOES USE THE INDEX BACKWARD
SCOTT@orcl_11g> SELECT
2 SNAME, I
3 FROM (
4 SELECT /*+ INDEX_DESC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME DESC, ID DESC
9 )
10 WHERE rownum<=22
11 /
SNAME I
-------------------------------------------------------------------------------- ----------
yCbCrSubSamplingType295_T 1
yCbCrPositioningType294_T 1
yCbCrCoefficientsType284_T 1
xmpMetadataType569_T 1
xdb-log13_TAB$xd 1
xdb-log13_TAB 1
xdb-log11_T 1
xdb-log-entry12_COLL 1
xdb-log-entry-type10_T 1
whitePointType287_T 1
whiteBalanceType279_T 1
uuidType272_T 1
timeType309_T 1
supplementalCategory564_COLL 1
sun/util/calendar/ZoneInfoFile 1
sun/util/calendar/ZoneInfoFile 2
sun/util/calendar/ZoneInfo 1
sun/util/calendar/ZoneInfo 2
sun/util/calendar/Gregorian 1
sun/util/calendar/Gregorian 2
sun/util/calendar/Era 1
sun/util/calendar/Era 2
22 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1730477067
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 1210 | 379 (1)| 00:00:05 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 68625 | 3685K| 379 (1)| 00:00:05 |
| 3 | WINDOW NOSORT | | 68625 | 2010K| 379 (1)| 00:00:05 |
| 4 | INDEX FULL SCAN DESCENDING| IDX_USE_ME | 68625 | 2010K| 379 (1)| 00:00:05 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=22)
SCOTT@orcl_11g>
SCOTT@orcl_11g> /* NOW LETS CREATE A DESCENDING INDEX FOR CASES C,D,E */
SCOTT@orcl_11g> DROP INDEX IDX_USE_ME;
Index dropped.
SCOTT@orcl_11g> CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME DESC, ID DESC)
2 /
Index created.
SCOTT@orcl_11g> -- MUST ANALYZE AGAIN:
SCOTT@orcl_11g> EXEC DBMS_STATS.GATHER_TABLE_STATS (USER, 'CUSTOMER')
PL/SQL procedure successfully completed.
SCOTT@orcl_11g> /* CASE C: THE ANALYTIC FN DOES NOT USE THE INDEX FORWARD*/
SCOTT@orcl_11g> -- ON MY SYSTEM IT DOES USE THE INDEX FORWARD
SCOTT@orcl_11g> SELECT
2 SNAME, I
3 FROM (
4 SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME DESC, ID DESC
9 ) a
10 WHERE rownum<=22
11 /
SNAME I
-------------------------------------------------------------------------------- ----------
yCbCrSubSamplingType295_T 1
yCbCrPositioningType294_T 1
yCbCrCoefficientsType284_T 1
xmpMetadataType569_T 1
xdb-log13_TAB$xd 1
xdb-log13_TAB 1
xdb-log11_T 1
xdb-log-entry12_COLL 1
xdb-log-entry-type10_T 1
whitePointType287_T 1
whiteBalanceType279_T 1
uuidType272_T 1
timeType309_T 1
supplementalCategory564_COLL 1
sun/util/calendar/ZoneInfoFile 1
sun/util/calendar/ZoneInfoFile 2
sun/util/calendar/ZoneInfo 1
sun/util/calendar/ZoneInfo 2
sun/util/calendar/Gregorian 1
sun/util/calendar/Gregorian 2
sun/util/calendar/Era 1
sun/util/calendar/Era 2
22 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1492562620
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 1210 | 33755 (1)| 00:06:46 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 68625 | 3685K| 33755 (1)| 00:06:46 |
| 3 | WINDOW NOSORT | | 68625 | 2010K| 33755 (1)| 00:06:46 |
| 4 | TABLE ACCESS BY INDEX ROWID| CUSTOMER | 68625 | 2010K| 33755 (1)| 00:06:46 |
| 5 | INDEX FULL SCAN | IDX_USE_ME | 68625 | | 398 (1)| 00:00:05 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=22)
SCOTT@orcl_11g> /* CASE D: THE ANALYTIC FN USES THE INDEX FORWARD AFTER COERCION WITH SYS_OP_DESCEND */
SCOTT@orcl_11g> SELECT
2 SNAME, I
3 FROM (
4 SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SYS_OP_DESCEND(SNAME) ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME DESC, ID DESC
9 ) a
10 WHERE rownum<=22
11 /
SNAME I
-------------------------------------------------------------------------------- ----------
yCbCrSubSamplingType295_T 1
yCbCrPositioningType294_T 1
yCbCrCoefficientsType284_T 1
xmpMetadataType569_T 1
xdb-log13_TAB$xd 1
xdb-log13_TAB 1
xdb-log11_T 1
xdb-log-entry12_COLL 1
xdb-log-entry-type10_T 1
whitePointType287_T 1
whiteBalanceType279_T 1
uuidType272_T 1
timeType309_T 1
supplementalCategory564_COLL 1
sun/util/calendar/ZoneInfoFile 1
sun/util/calendar/ZoneInfoFile 2
sun/util/calendar/ZoneInfo 1
sun/util/calendar/ZoneInfo 2
sun/util/calendar/Gregorian 1
sun/util/calendar/Gregorian 2
sun/util/calendar/Era 1
sun/util/calendar/Era 2
22 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3940838639
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 1210 | 2276 (1)| 00:00:28 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 68625 | 3685K| 2276 (1)| 00:00:28 |
| 3 | WINDOW NOSORT | | 68625 | 3752K| 2276 (1)| 00:00:28 |
| 4 | INDEX FULL SCAN| IDX_USE_ME | 68625 | 3752K| 398 (1)| 00:00:05 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=22)
SCOTT@orcl_11g> /* CASE E: THE ANALYTIC FN DOES NOT USE THE INDEX BACKWARD */
SCOTT@orcl_11g> -- THIS IS THE ONLY ONE THAT DOES NOT USE THE INDEX ON MY SYSTEM
SCOTT@orcl_11g> SELECT
2 SNAME, I
3 FROM (
4 SELECT /*+ INDEX_DESC(IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 ) a
10 WHERE rownum<=22
11 /
SNAME I
-------------------------------------------------------------------------------- ----------
/1000323d_DelegateInvocationHa 1
/1000323d_DelegateInvocationHa 2
/1000e8d1_LinkedHashMapValueIt 1
/1000e8d1_LinkedHashMapValueIt 2
/1005bd30_LnkdConstant 1
/1005bd30_LnkdConstant 2
/10076b23_OraCustomDatumClosur 1
/10076b23_OraCustomDatumClosur 2
/100c1606_StandardMidiFileRead 1
/100c1606_StandardMidiFileRead 2
/100cb3d7_DicomLocatorPathDico 1
/100cb3d7_DicomLocatorPathDico 2
/10128284_OpenMBeanAttributeIn 1
/10128284_OpenMBeanAttributeIn 2
/1013c29d_PlanarImageServerPro 1
/1013c29d_PlanarImageServerPro 2
/101419a4_NormalDataCollector 1
/101419a4_NormalDataCollector 2
/1020ed5e_Param 1
/1020ed5e_Param 2
/1023e902_OraCharsetUTFE 1
/1023e902_OraCharsetUTFE 2
22 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1603918779
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 1210 | 171 (1)| 00:00:03 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 68625 | 3685K| 171 (1)| 00:00:03 |
| 3 | WINDOW SORT | | 68625 | 2010K| 171 (1)| 00:00:03 |
| 4 | TABLE ACCESS FULL| CUSTOMER | 68625 | 2010K| 171 (1)| 00:00:03 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=22)
SCOTT@orcl_11g> SET AUTOTRACE OFF
-- script:
DROP TABLE CUSTOMER
/
CREATE TABLE CUSTOMER
(
ID NUMBER(10),
SNAME VARCHAR2(80 BYTE) NOT NULL,
FNAME VARCHAR2(50 BYTE),
DOB DATE
)
/
INSERT INTO CUSTOMER (ID, FNAME, SNAME, DOB)
SELECT rownum, CHR(mod(rownum,26)+64) || substr(to_char(TIMESTAMP),4,14), to_char(OBJECT_NAME), LAST_DDL_TIME
FROM ALL_OBJECTS
/
CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME ASC, ID ASC)
/
exec DBMS_STATS.GATHER_TABLE_STATS (USER, 'CUSTOMER')
/* CASE A: THE ANALYTIC FN USES THE INDEX FORWARD*/
SET AUTOTRACE ON EXPLAIN
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME ASC, ID ASC
)
WHERE rownum<=22
/
/* CASE B: THE ANALYTIC FN DOES NOT USE THE INDEX BACKWARD*/
-- ON MY SYSTEM, IT DOES USE THE INDEX BACKWARD
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_DESC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME DESC, ID DESC
)
WHERE rownum<=22
/
/* NOW LETS CREATE A DESCENDING INDEX FOR CASES C,D,E */
DROP INDEX IDX_USE_ME;
CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME DESC, ID DESC)
/
-- MUST ANALYZE AGAIN:
EXEC DBMS_STATS.GATHER_TABLE_STATS (USER, 'CUSTOMER')
/* CASE C: THE ANALYTIC FN DOES NOT USE THE INDEX FORWARD*/
-- ON MY SYSTEM IT DOES USE THE INDEX FORWARD
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME DESC, ID DESC
) a
WHERE rownum<=22
/
/* CASE D: THE ANALYTIC FN USES THE INDEX FORWARD AFTER COERCION WITH SYS_OP_DESCEND */
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_ASC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SYS_OP_DESCEND(SNAME) ORDER BY SNAME DESC, ID DESC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME DESC, ID DESC
) a
WHERE rownum<=22
/
/* CASE E: THE ANALYTIC FN DOES NOT USE THE INDEX BACKWARD */
-- THIS IS THE ONLY ONE THAT DOES NOT USE THE INDEX ON MY SYSTEM
SELECT
SNAME, I
FROM (
SELECT /*+ INDEX_DESC(IDX_USE_ME) FIRST_ROWS*/
row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
SNAME
FROM CUSTOMER
ORDER BY SNAME ASC, ID ASC
) a
WHERE rownum<=22
/
SET AUTOTRACE OFF
|
|
|
|
|
|
Re: Analytical Functions and Backward Index scans [message #307700 is a reply to message #307386] |
Wed, 19 March 2008 09:56 |
verpies
Messages: 28 Registered: March 2008 Location: Seattle
|
Junior Member |
|
|
Dear All,
Yes, I asked in other places. I hope the members of this forum do not treat it as cross posting. After all, it's a different forum.
First of all, I'd like to share that the hint format in my test case WAS wrong. Very wrong!
It was /*+ INDEX_DESC(INDEX_NAME) */
...and it should be at least:
/*+ INDEX_DESC(TABLE_ALIAS INDEX_NAME) */
...and, should be at most:
http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10752/hintsref.htm#22275
Now, just to pardon myself: In the past, I was using the complex index hint syntax depicted at the URL above, but found out that it does not work when refeing to COLUMN NAMES in a descending index (Tom Kyte confirmed that).
Thus, I did a quick Search&Replace and messed up the table alias in the process. Sorry about that - to err is human...
Now, after correcting the hint syntax I get the same results as Barbara (one of the problems is gone
The second problem is still there
The CASE E still does not use the descending index backward.
I was able to coerce CASE E into good behavior with the SYS_OP_DESCEND function, though.
If anyone has an idea how to avoid using SYS_OP_DESCEND, please speak up.
Thanks for all your help guys,
George Robinson
|
|
|
Re: Analytical Functions and Backward Index scans [message #307711 is a reply to message #307700] |
Wed, 19 March 2008 11:36 |
|
Barbara Boehmer
Messages: 9100 Registered: November 2002 Location: California, USA
|
Senior Member |
|
|
There is no problem with posting on other forums and it is not considered cross-posting. Sometimes it helps to provide links so that we avoid duplicating what someone else has already done. We usually wait until we have exhausted all efforts ourselves or have disagreement amongst ourselves, before going to Tom Kyte. Once we get to the point, we usually just sit back and wait for the grand master of all Oracle gurus to respond and it appears that you have already gone to that point. However, apparently most Oracle employees are busy with the latest Oracle conference or whatever as they are noticably absent from the OTN forums and such, so it could be a while.
For the most part, the optimizer does a good job of selecting the best execution plan, but there are exceptions. Sometimes it is hard to tell whether what we are trying to force it to do is better than what it is doing, so it is hard to tell when to give hints and when not to and why it chooses to ignore them. Some little things like why it makes a difference if you provide the table name for a query that only selects from one table can be baffling. Here is my latest experiment for case E:
SCOTT@orcl_11g> CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME DESC, ID DESC)
2 /
Index created.
SCOTT@orcl_11g> EXEC DBMS_STATS.GATHER_TABLE_STATS (USER, 'CUSTOMER')
PL/SQL procedure successfully completed.
SCOTT@orcl_11g> SELECT
2 SNAME, I
3 FROM (
4 SELECT /*+ INDEX_DESC(customer IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 ) a
10 WHERE rownum<=22
11 /
SNAME I
-------------------------------------------------------------------------------- ----------
/1000323d_DelegateInvocationHa 1
/1000323d_DelegateInvocationHa 2
/1000e8d1_LinkedHashMapValueIt 1
/1000e8d1_LinkedHashMapValueIt 2
/1005bd30_LnkdConstant 1
/1005bd30_LnkdConstant 2
/10076b23_OraCustomDatumClosur 1
/10076b23_OraCustomDatumClosur 2
/100c1606_StandardMidiFileRead 1
/100c1606_StandardMidiFileRead 2
/100cb3d7_DicomLocatorPathDico 1
/100cb3d7_DicomLocatorPathDico 2
/10128284_OpenMBeanAttributeIn 1
/10128284_OpenMBeanAttributeIn 2
/1013c29d_PlanarImageServerPro 1
/1013c29d_PlanarImageServerPro 2
/101419a4_NormalDataCollector 1
/101419a4_NormalDataCollector 2
/1020ed5e_Param 1
/1020ed5e_Param 2
/1023e902_OraCharsetUTFE 1
/1023e902_OraCharsetUTFE 2
22 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 494970170
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 1210 | 33756 (1)| 00:06:46 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 68627 | 3686K| 33756 (1)| 00:06:46 |
|* 3 | SORT ORDER BY STOPKEY | | 68627 | 2010K| 33756 (1)| 00:06:46 |
| 4 | WINDOW SORT | | 68627 | 2010K| 33756 (1)| 00:06:46 |
| 5 | TABLE ACCESS BY INDEX ROWID| CUSTOMER | 68627 | 2010K| 33756 (1)| 00:06:46 |
| 6 | INDEX FULL SCAN DESCENDING| IDX_USE_ME | 68627 | | 398 (1)| 00:00:05 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=22)
3 - filter(ROWNUM<=22)
SCOTT@orcl_11g>
[Updated on: Wed, 19 March 2008 11:47] Report message to a moderator
|
|
|
Re: Analytical Functions and Backward Index scans [message #307719 is a reply to message #307386] |
Wed, 19 March 2008 12:07 |
verpies
Messages: 28 Registered: March 2008 Location: Seattle
|
Junior Member |
|
|
Barbara & All,
Thanks for your help.
I was fighting with this problem since November 2007 (see Tom's forum).
I got so exasperated with it that I asked for help in many places and decided to use the undocumented SYS_OP_DESCEND function.
Now, I need to test if it still works with the NLSSORT function inside. Like this:
SYS_OP_DESCEND( NLSSORT(columname) ).
NLSSORT goes inside the SYS_OP_DESCEND, right ?
Below is my latest experiment with Case E.
I sprinkled SYS_OP_DESCEND here and there and named it Case F.
Voila! Query plan shows WINDOW NOSORT
Regards,
George
P.S.
I have no idea where your TABLE ACCESS BY INDEX ROWID comes from...
SQL> DROP INDEX IDX_USE_ME;
Index dropped.
SQL> CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME ASC, ID ASC);
Index created.
SQL> exec DBMS_STATS.GATHER_INDEX_STATS (ownname => 'ORAUSER', indname => 'IDX_USE_ME');
PL/SQL procedure successfully completed.
SQL>
SQL> /* CASE A: THE ANALYTIC FN USES THE ASCENDING INDEX FORWARD*/
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_ASC(CUSTOMER IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 )
10 WHERE rownum<=9;
I SNAME
---------- --------------------------------------------------------------------------------
1 /1000e8d1_LinkedHashMapValueIt
2 /1000e8d1_LinkedHashMapValueIt
1 /1005bd30_LnkdConstant
2 /1005bd30_LnkdConstant
1 /10076b23_OraCustomDatumClosur
2 /10076b23_OraCustomDatumClosur
1 /100c1606_StandardMidiFileRead
2 /100c1606_StandardMidiFileRead
1 /1013c29d_PlanarImageServerPro
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3940838639
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | 689 (2)| 00:00:09 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 49849 | 2677K| 689 (2)| 00:00:09 |
| 3 | WINDOW NOSORT | | 49849 | 1460K| 689 (2)| 00:00:09 |
| 4 | INDEX FULL SCAN| IDX_USE_ME | 49849 | 1460K| 274 (1)| 00:00:04 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
SQL>
SQL>
SQL> /* CASE B: THE ANALYTIC FN USES THE ASCENDING INDEX BACKWARD*/
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_DESC(CUSTOMER IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME DESC, ID DESC
9 )
10 WHERE rownum<=9;
I SNAME
---------- --------------------------------------------------------------------------------
1 yCbCrSubSamplingType221_T
1 yCbCrPositioningType220_T
1 yCbCrCoefficientsType210_T
1 xmpMetadataType100_T
1 xml-extension-type31_T
1 xdbconfig60_T
1 xdb-log9_TAB$xd
1 xdb-log9_TAB
1 xdb-log7_T
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1730477067
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | 1105 (2)| 00:00:14 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 49849 | 2677K| 1105 (2)| 00:00:14 |
| 3 | WINDOW NOSORT | | 49849 | 1460K| 1105 (2)| 00:00:14 |
| 4 | INDEX FULL SCAN DESCENDING| IDX_USE_ME | 49849 | 1460K| 274 (1)| 00:00:04 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
SQL> /* NOW LETS CREATE A DESCENDING INDEX FOR CASES C,D,E,F */
SQL> DROP INDEX IDX_USE_ME;
Index dropped.
SQL> CREATE UNIQUE INDEX IDX_USE_ME ON CUSTOMER (SNAME DESC, ID DESC);
Index created.
SQL> exec DBMS_STATS.GATHER_INDEX_STATS (ownname => 'ORAUSER', indname => 'IDX_USE_ME');
PL/SQL procedure successfully completed.
SQL>
SQL> /* CASE C: THE ANALYTIC FN DOES NOT USE THE DESCENDING INDEX FORWARD*/
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_ASC(CUSTOMER IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME DESC, ID DESC
9 ) a
10 WHERE rownum<=9;
I SNAME
---------- --------------------------------------------------------------------------------
1 yCbCrSubSamplingType221_T
1 yCbCrPositioningType220_T
1 yCbCrCoefficientsType210_T
1 xmpMetadataType100_T
1 xml-extension-type31_T
1 xdbconfig60_T
1 xdb-log9_TAB$xd
1 xdb-log9_TAB
1 xdb-log7_T
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 733892884
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | | 1119 (2)| 00:00:14 |
|* 1 | COUNT STOPKEY | | | | | | |
| 2 | VIEW | | 49849 | 2677K| | 1119 (2)| 00:00:14 |
|* 3 | SORT ORDER BY STOPKEY| | 49849 | 1460K| 3928K| 1119 (2)| 00:00:14 |
| 4 | WINDOW SORT | | 49849 | 1460K| 3928K| 1119 (2)| 00:00:14 |
| 5 | INDEX FULL SCAN | IDX_USE_ME | 49849 | 1460K| | 288 (1)| 00:00:04 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
3 - filter(ROWNUM<=9)
SQL>
SQL>
SQL> /* CASE D: THE ANALYTIC FN USES THE DESCENDING INDEX FORWARD AFTER COERCION WITH SYS_OP_DESCEND */
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_ASC(CUSTOMER IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SYS_OP_DESCEND(SNAME) ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME DESC, ID DESC
9 ) a
10 WHERE rownum<=9;
I SNAME
---------- --------------------------------------------------------------------------------
1 yCbCrSubSamplingType221_T
1 yCbCrPositioningType220_T
1 yCbCrCoefficientsType210_T
1 xmpMetadataType100_T
1 xml-extension-type31_T
1 xdbconfig60_T
1 xdb-log9_TAB$xd
1 xdb-log9_TAB
1 xdb-log7_T
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3940838639
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | 1119 (2)| 00:00:14 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 49849 | 2677K| 1119 (2)| 00:00:14 |
| 3 | WINDOW NOSORT | | 49849 | 1460K| 1119 (2)| 00:00:14 |
| 4 | INDEX FULL SCAN| IDX_USE_ME | 49849 | 1460K| 288 (1)| 00:00:04 |
---------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
SQL>
SQL>
SQL> /* CASE E: THE ANALYTIC FN DOES NOT USE THE DESCENDING INDEX BACKWARD */
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_DESC(CUSTOMER IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME ASC, ID ASC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 ) a
10 WHERE rownum<=9;
I SNAME
---------- --------------------------------------------------------------------------------
1 /1000e8d1_LinkedHashMapValueIt
2 /1000e8d1_LinkedHashMapValueIt
1 /1005bd30_LnkdConstant
2 /1005bd30_LnkdConstant
1 /10076b23_OraCustomDatumClosur
2 /10076b23_OraCustomDatumClosur
1 /100c1606_StandardMidiFileRead
2 /100c1606_StandardMidiFileRead
1 /1013c29d_PlanarImageServerPro
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2375959224
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | | 703 (2)| 00:00:09 |
|* 1 | COUNT STOPKEY | | | | | | |
| 2 | VIEW | | 49849 | 2677K| | 703 (2)| 00:00:09 |
|* 3 | SORT ORDER BY STOPKEY | | 49849 | 1460K| 3928K| 703 (2)| 00:00:09 |
| 4 | WINDOW SORT | | 49849 | 1460K| 3928K| 703 (2)| 00:00:09 |
| 5 | INDEX FULL SCAN DESCENDING| IDX_USE_ME | 49849 | 1460K| | 288 (1)| 00:00:04 |
-----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
3 - filter(ROWNUM<=9)
SQL>
SQL>
SQL>
SQL> /* CASE F: THE ANALYTIC FN USES THE DESCENDING INDEX BACKWARD AFTER COERCION WITH SYS_OP_DESCEND */
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_DESC(CUSTOMER IDX_USE_ME) FIRST_ROWS */
5 row_number() OVER (PARTITION BY SYS_OP_DESCEND(SNAME) ORDER BY SYS_OP_DESCEND(SNAME) DESC, SYS_OP_DESCEND(ID) DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 ) a
10 WHERE rownum<=9;
I SNAME
---------- --------------------------------------------------------------------------------
1 /1000e8d1_LinkedHashMapValueIt
2 /1000e8d1_LinkedHashMapValueIt
1 /1005bd30_LnkdConstant
2 /1005bd30_LnkdConstant
1 /10076b23_OraCustomDatumClosur
2 /10076b23_OraCustomDatumClosur
1 /100c1606_StandardMidiFileRead
2 /100c1606_StandardMidiFileRead
1 /1013c29d_PlanarImageServerPro
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1730477067
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | 1119 (2)| 00:00:14 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 49849 | 2677K| 1119 (2)| 00:00:14 |
| 3 | WINDOW NOSORT | | 49849 | 1460K| 1119 (2)| 00:00:14 |
| 4 | INDEX FULL SCAN DESCENDING| IDX_USE_ME | 49849 | 1460K| 288 (1)| 00:00:04 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
SQL>
[Updated on: Wed, 19 March 2008 13:34] Report message to a moderator
|
|
|
Re: Analytical Functions and Backward Index scans [message #308007 is a reply to message #307386] |
Thu, 20 March 2008 14:50 |
coleing
Messages: 213 Registered: February 2008
|
Senior Member |
|
|
Here is something interesting:-
Could it be the "partition by" clause causing all the grief?. partition by column name seems to always want to partition the data by having it in ascending order.
Turn it into a function index, and its different
SQL> DROP INDEX IDX_USE_ME;
Index dropped.
SQL>
SQL> CREATE INDEX IDX_USE_ME ON CUSTOMER (SNAME, SNAME DESC, ID DESC);
Index created.
SQL>
SQL>
SQL> exec DBMS_STATS.GATHER_INDEX_STATS (ownname => 'SYSTEM', indname => 'IDX_USE_ME');
PL/SQL procedure successfully completed.
SQL> exec DBMS_STATS.GATHER_TABLE_STATS (ownname => 'SYSTEM', tabname => 'CUSTOMER');
PL/SQL procedure successfully completed.
SQL>
SQL> /* CASE G WITH EXTRA COLUMN IN INDEX ASCENDING ORDER TO CATER FOR PARTITION BY */
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_ASC(CUSTOMER IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY SNAME ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 ) a
10 WHERE rownum<=9;
I SNAME
---------- --------------------------------------------------------------------------------
2 /1000e8d1_LinkedHashMapValueIt
1 /1000e8d1_LinkedHashMapValueIt
2 /1005bd30_LnkdConstant
1 /1005bd30_LnkdConstant
2 /10076b23_OraCustomDatumClosur
1 /10076b23_OraCustomDatumClosur
2 /100c1606_StandardMidiFileRead
1 /100c1606_StandardMidiFileRead
2 /1013c29d_PlanarImageServerPro
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 733892884
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | | 1358 (2)| 00:00:17 |
|* 1 | COUNT STOPKEY | | | | | | |
| 2 | VIEW | | 53160 | 2855K| | 1358 (2)| 00:00:17 |
|* 3 | SORT ORDER BY STOPKEY| | 53160 | 1505K| 4184K| 1358 (2)| 00:00:17 |
| 4 | WINDOW SORT | | 53160 | 1505K| 4184K| 1358 (2)| 00:00:17 |
| 5 | INDEX FULL SCAN | IDX_USE_ME | 53160 | 1505K| | 493 (1)| 00:00:06 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
3 - filter(ROWNUM<=9)
SQL>
SQL>
SQL>
SQL>
SQL> DROP INDEX IDX_USE_ME;
Index dropped.
SQL>
SQL> CREATE INDEX IDX_USE_ME ON CUSTOMER (UPPER(SNAME), SNAME DESC, ID DESC);
Index created.
SQL>
SQL>
SQL> exec DBMS_STATS.GATHER_INDEX_STATS (ownname => 'SYSTEM', indname => 'IDX_USE_ME');
PL/SQL procedure successfully completed.
SQL> exec DBMS_STATS.GATHER_TABLE_STATS (ownname => 'SYSTEM', tabname => 'CUSTOMER');
PL/SQL procedure successfully completed.
SQL>
SQL> /* CASE H WITH EXTRA COLUMN IN INDEX ASCENDING ORDER TO CATER FOR PARTITION BY */
SQL> SELECT
2 I, SNAME
3 FROM (
4 SELECT /*+ INDEX_ASC(CUSTOMER IDX_USE_ME) FIRST_ROWS*/
5 row_number() OVER (PARTITION BY UPPER(SNAME) ORDER BY SNAME DESC, ID DESC) I,
6 SNAME
7 FROM CUSTOMER
8 ORDER BY SNAME ASC, ID ASC
9 ) a
10 WHERE rownum<=9;
I SNAME
---------- --------------------------------------------------------------------------------
2 /1000e8d1_LinkedHashMapValueIt
1 /1000e8d1_LinkedHashMapValueIt
2 /1005bd30_LnkdConstant
1 /1005bd30_LnkdConstant
2 /10076b23_OraCustomDatumClosur
1 /10076b23_OraCustomDatumClosur
2 /100c1606_StandardMidiFileRead
1 /100c1606_StandardMidiFileRead
2 /1013c29d_PlanarImageServerPro
9 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2846590933
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 495 | | 925 (2)| 00:00:12 |
|* 1 | COUNT STOPKEY | | | | | | |
| 2 | VIEW | | 53160 | 2855K| | 925 (2)| 00:00:12 |
|* 3 | SORT ORDER BY STOPKEY| | 53160 | 1505K| 4184K| 925 (2)| 00:00:12 |
| 4 | WINDOW NOSORT | | 53160 | 1505K| | 925 (2)| 00:00:12 |
| 5 | INDEX FULL SCAN | IDX_USE_ME | 53160 | 1505K| | 493 (1)| 00:00:06 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=9)
3 - filter(ROWNUM<=9)
SQL>
SQL>
SQL>
[Updated on: Thu, 20 March 2008 14:54] Report message to a moderator
|
|
|
Re: Analytical Functions and Backward Index scans [message #308020 is a reply to message #308007] |
Thu, 20 March 2008 15:48 |
verpies
Messages: 28 Registered: March 2008 Location: Seattle
|
Junior Member |
|
|
coleing,
It definitely is the PARTITION BY clause!
It just does not recognize descending columns in indexes. Aaaaarrrggggghhhh
I prefer the SYS_OP_DESCEND trick because it allows me to reuse an existing index and does not force me to create a new one.
Do you think the whole PARTITION BY DESC issue can be considered a bug ?
Regards,
George Robinson
[Updated on: Thu, 20 March 2008 15:49] Report message to a moderator
|
|
|
|
Goto Forum:
Current Time: Tue Nov 26 19:24:34 CST 2024
|